TikZ で関数の合計をプロットする

TikZ で関数の合計をプロットする

パラメータに基づいて別の関数の合計となる関数をプロットしようとしています。

この有名な例は「平方和」ですが、私が実際にこれを実行したい関数には明示的な式がありません。

次の例は、私が得たい結果と、それを得るための方法を示していますが、明らかに正しい結果は得られていません。

\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}%
  }

コードには 2 つの問題があります。

  • まず、\foreachネストされたグループ化を導入し、\retグループ内に閉じ込められます。
  • 第二に、FPU をアクティブにすると、になり\pgfmathtruncatemacro\cnt{#1}ます。 \cnt1
    • (これは実際にはフラグ#1FPU 表現での 。
    • フラグ 1正の数を表します。

最初の障害を乗り越えるために、私は通常、\xdef価値を密輸するために使用します。また、は を導入します\pgfplotsforeachungrouped。これは文字通り のグループ化されていないバージョンです\foreach

2 番目の障害については、マニュアルを注意深く確認し、それが\pgfmathfloattoint{#1}\let\cnt\pgfmathresult作業を行う正しい方法であることを確認する必要があります。


こうすると、 とは異なる曲線が得られ、 が正しい式ではないexplicit_sumことがわかります。#1*(#1-1)/2

関連情報