例如,我想获取一个包含值的数组sin(1),sin(2),..,sin(100)
并将其存储到变量中。有没有办法通过使用来获得此结果foreach
?
编辑:一个更复杂的例子:绘制 100 个随机点{(1,rnd),(2,rnd),...,(10,rnd)}
,然后绘制从这些点到它们的平均值的距离。
我不知道如何在 tikz 中实现它,这里是伪代码:
yarray = {} //an array to store 100 random value
sum = 0
for i = {1...100}
yarray[i] = random
sum = sum + yarray[i]
mean = sum/100
absarray = {} //an array to store the distance from points to mean
for i = {1...100}
absarray[i] = abs(yarray[i]-mean)
// draw the image
for i = {1...100}
\fill (i,yarray[i]) circle (2pt)
\fill (i,absarray[i]) circle (2pt)
答案1
这是一种方法。
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand\store[6][\x]{%
% #1 = dummy variable
% #2 = variable to store the list
% #3 = expression
% #4 = expression to store (with \pgfmathresult) and possibly #1
% #5 = start point
% #6 = end point
\gdef\store@temp{\@gobble}%
\foreach #1 in {#5,...,#6}{\pgfmathparse{#3}\xdef\store@temp{\store@temp,#4}}%
\let#2=\store@temp
}
\makeatother
\begin{document}
\store{\sineslist}{sin(deg(\x))}{\pgfmathresult}{1}{100}
\show\sineslist
\store[\i]{\randlist}{rand}{(\i,\pgfmathresult)}{1}{20}
\show\randlist
\end{document}
报道内容如下:
> \sineslist=macro:
->0.84143,0.90924,0.14111,-0.75677,-0.95886,-0.27939,0.65697,0.9893,0.41208,-0.
544,-0.99995,-0.53654,0.42015,0.99057,0.65025,-0.28787,-0.96138,-0.75095,0.1498
6,0.91292,0.83662,-0.00885,-0.84619,-0.90555,-0.13234,0.76251,0.95636,0.27087,-
0.6636,-0.988,-0.40402,0.55139,0.99988,0.52907,-0.42815,-0.99173,-0.64352,0.296
34,0.96375,0.74509,-0.1586,-0.91647,-0.83174,0.01768,0.85086,0.90175,0.12357,-0
.7682,-0.9537,-0.26234,0.67021,0.98657,0.3959,-0.55878,-0.99971,-0.52153,0.4361
4,0.99284,0.6367,-0.30478,-0.9661,-0.73914,0.16733,0.92,0.8268,-0.02654,-0.8554
7,-0.8979,-0.11476,0.77385,0.95105,0.2538,-0.67673,-0.98512,-0.38777,0.56606,0.
99948,0.51398,-0.44408,-0.99385,-0.62988,0.3132,0.9683,0.73317,-0.17606,-0.9234
,-0.82178,0.03539,0.86002,0.89395,0.10597,-0.77942,-0.94824,-0.24522,0.68324,0.
98354,0.3796,-0.57335,-0.99916,-0.50635.
> \randlist=macro:
->(1,-0.86513),(2,-0.8214),(3,0.83136),(4,0.03825),(5,0.0602),(6,0.65846),(7,-0
.7918),(8,0.8938),(9,-0.13474),(10,-0.90755),(11,0.68077),(12,-0.1404),(13,-0.4
3602),(14,-0.08235),(15,0.65369),(16,-0.25284),(17,0.98817),(18,-0.09077),(19,0
.42735),(20,0.88712).
答案2
我不得不说,我没有理解你问题中的距离参数。我不会使用 PGF 或 TikZ,而是生成存储在文件中的数据数组。这样你就可以访问pgfplotstable
并且它的宏非常快。TikZ 部分在 150 左右就卡住了,但后面的例子就跑得相当远了(当然还有一个原因是我的代码根本没有优化,所以这不仅仅是 TikZ 的错)。
这是一个包含 100 个样本点的示例,仅将其存储到数组中并稍后读取它们,也是我从手册 + 一些调整中编译的 PGFPLOTSTABLE 示例。
\documentclass{article}
\usepackage{pgfplotstable,booktabs}
%\pgfmathsetseed{226584}
\def\sample{100}
\pgfmathsetmacro{\runningrandarray}{rand} % Initial
\edef\runningmean{\runningrandarray}
\foreach \x[count=\xi from 1] in {2,...,\sample}{
\let\temprand\runningrandarray
\pgfmathsetmacro\tempres{rand}
\xdef\runningrandarray{\temprand,\tempres}
\pgfmathparse{(\xi*\runningmean+\tempres)/\x}
\xdef\runningmean{\pgfmathresult}
}
\xdef\randarray{{\runningrandarray}} % Double brace needed if you want to access via TikZ
\begin{document}
Some random points here :
\begin{tikzpicture}
\foreach \x in {0,...,\number\numexpr\sample-1\relax}{
\pgfmathsetmacro\ycoord{\randarray[\x]}
\node[circle,inner sep=1pt,fill=red,ultra thin] at (\x mm,\ycoord mm){};
}
\end{tikzpicture}
and their current mean value is \runningmean
Instead we can directly go with PGFPLOTSTABLE package to produce the values:
\pgfplotstablenew[
create on use/y/.style={create col/expr={\pgfplotstablerow+1}},
% define how the 'sine' column shall be filled:
create on use/sine/.style={create col/expr={sin(\pgfplotstablerow+1)}},
columns={y,sine}]{130}\loadedtable
\vspace{1cm}
\begin{minipage}[t]{0.58\textwidth}
show it as a table (columns skipped):
\centering
\pgfplotstabletypeset[
every head row/.style={before row=\toprule,after row=\midrule},
every last row/.style={after row=\bottomrule},
row predicate/.code={%
\ifnum#1>5\relax
\ifnum#1<125\relax
\pgfplotstableuserowfalse
\fi
\fi}
]
\loadedtable
\end{minipage}
\begin{minipage}[t]{0.4\textwidth}
or directly use it in plots
\begin{tikzpicture}
\begin{axis}[width=4cm,height=7cm,xlabel={angle [deg]}]
\addplot[no marks] table[x=y,y=sine]\loadedtable;
\end{axis}
\end{tikzpicture}
\end{minipage}
\end{document}
答案3
不幸的是,我不知道如何处理与扩展相关的问题,因此无法为您提供简单的解决方案(尝试被注释掉了)。但是,我了解到使用包裹datatool
对我来说效果很好:
笔记:
- 我手动遍历数据库而不是使用,
\DTLdisplaydb
以便您可以看到如何遍历它(有趣的是您需要单独的条目)。 - 这里的扩展专家可以向您展示如何扩展要存储的结果,但下面我尝试使用其中一种解决方案如何保存字符串的运行列表,然后逐个处理它们保存值列表
sin
。
代码:
\documentclass{article}
\usepackage{tikz}
\usepackage{datatool}
%% https://tex.stackexchange.com/questions/14393/how-keep-a-running-list-of-strings-and-then-process-them-one-at-a-time
%\def\ListOfValues{}
%\makeatletter
%\newcommand{\AddToListOfValues}[1]{%
% \g@addto@macro\ListOfValues{{#1}}%
%}
%\makeatother
\begin{document}
\DTLnewdb{TableOfSinValues}
\foreach \x in {1,...,10} {%
\pgfmathparse{sin(deg(\x))}
%\edef\temp\pgfmathresult
%\AddToListOfValues{\temp}%
\DTLnewrow{TableOfSinValues}
\dtlexpandnewvalue
\DTLnewdbentry{TableOfSinValues}{Degree}{\x}
\DTLnewdbentry{TableOfSinValues}{SinValue}{\pgfmathresult}
}%
List of $\sin$ Values:\bigskip
%\DTLdisplaydb{TableOfSinValues}% for automated display
\begin{tabular}{cr}
$x$ [degrees] & $\sin{x}$ \\[0.5ex]
\DTLforeach{TableOfSinValues}{\Degree=Degree, \SinValue=SinValue}{%
$\Degree$ & $\SinValue$\\
}%
\end{tabular}
\end{document}