我正在尝试绘制一个基于参数的另一个函数之和的函数。
一个著名的例子是“平方和”,但我真正想要执行此操作的函数并没有明确的公式。
下面的例子显示了我想要得到的结果和我想要得到它的方法,但显然它没有给出正确的结果。
\documentclass[border=10]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\begin{document}
% Explicit formula
\pgfmathdeclarefunction{explicit_sum}{1}{%
\pgfmathparse{(#1*(#1-1))/2}%
}
% The inner function
\pgfmathdeclarefunction{square}{1}{%
\pgfmathparse{#1*#1}%
}
% Compute the sum of another function
% Does not work...
\pgfmathdeclarefunction{manual_sum}{1}{%
%Parameter should be integral
\pgfmathtruncatemacro\cnt{#1}
\pgfmathsetmacro\ret{0}
\foreach \i in {1,...,\cnt} {
\pgfmathsetmacro\ret{\ret + sum(\i)}
}
\pgfmathparse{\ret}
}
\begin{tikzpicture}
\begin{axis}
% Expected
\addplot[samples at={1,...,10}] {explicit_sum(x)};
% Does not work
\addplot[samples at={1,...,10}] {manual_sum(x)};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
如果允许生成一个“不可见”表来定义 x 值,然后在另一列中进行计算,那么您可以执行以下操作。
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
% Explicit formula
\pgfmathdeclarefunction{explicit_sum}{1}{%
\pgfmathparse{(#1*(#1-1))/2}%
}
\pgfplotstableset{
% define how the 'x' column shall be filled
% (in this case just with integers counting from 1)
create on use/x/.style={
create col/set list={1,...,100}
},
% -----
% now you can either create here a column with your function ...
create on use/fx/.style={
create col/expr={(\thisrow{x})^2}
},
% ... and then accumulate the values here ...
create on use/sum/.style={
create col/expr accum={
\pgfmathaccuma + \thisrow{fx}
}{0}, % <-- start with `0'
},
% -----
% ... or you accumulate directly with the function
create on use/sum2/.style={
create col/expr accum={
\pgfmathaccuma + (\thisrow{x})^2
}{0}, % <-- start with `0'
},
% -----
}
% here you create a new table using the columns you need and
% with the first mandatory argument you specify the number of elements
% the table should have
% (so either `sum2' is redundant or (`fx' and `sum') are redundant)
\pgfplotstablenew[
columns={x,fx,sum,sum2},
]{10}{\loadedtable}
\begin{document}
% % maybe it is useful to typeset the table for debugging purposes
% \pgfplotstabletypeset[
% columns={x,fx,sum,sum2},
% ]{\loadedtable}
\begin{tikzpicture}
\begin{axis}[
% added for debugging purposes or here to quicker check,
% it one gets the desired output
nodes near coords,
]
% Expected
\addplot+[samples at={1,...,10}] {explicit_sum(x)};
% when the table is created, you can use the columns here
\addplot table [x=x,y=sum] {\loadedtable};
\end{axis}
\end{tikzpicture}
\end{document}
答案2
TL; DR,函数声明应该是
\pgfmathdeclarefunction{manual_sum}{1}{%
\pgfmathfloattoint{#1}\let\cnt\pgfmathresult%
\pgfmathsetmacro\ret{0}%
\foreach\i in{1,...,\cnt}{%
\pgfmathsetmacro\ret{\ret+\i} % summing integer itself
%\pgfmathsetmacro\ret{\ret+square(\i)} % general case
\xdef\ret{\ret}%
}%
\pgfmathparse{\ret}%
}
您的代码有两个问题:
- 首先,
\foreach
引入嵌套分组并\ret
陷入分组之中。 - 第二,由于pgf图激活FPU后,
\pgfmathtruncatemacro\cnt{#1}
将会\cnt
使1
。- (这实际上是旗帜在
#1
FPU 表示中。) - (旗帜
1
代表正数。
- (这实际上是旗帜在
为了克服第一个障碍,我通常使用\xdef
偷运价值。还值得注意的是pgf图介绍\pgfplotsforeachungrouped
,这实际上是一个未分组的版本\foreach
。
对于第二个障碍,需要仔细检查手册并找到\pgfmathfloattoint{#1}\let\cnt\pgfmathresult
正确的完成工作的方法。
这将给你带来一条不同于的曲线explicit_sum
,然后你就会意识到那#1*(#1-1)/2
不是正确的公式。