绘制具有条件基函数的递归定义函数集

绘制具有条件基函数的递归定义函数集

我试图通过逐步展示曲线的创建方式来可视化 B 样条函数的构造。这涉及绘制类似以下的曲线: B 样条图

创建曲线的函数是递归定义的: 函数公式

我尝试将 t0 到 t5 定义为一个列表\def\tvalues{{53,125,172,248,286,338,415}},并创建 N_i^1(t) 作为我可以调用的函数:

\pgfmathdeclarefunction{bsplinebase}{}{\pgfmathparse{(and(#1>=\tvalues[#2], #1<\tvalues[#2+1]))}

效果不太好。问题似乎出在列表访问上,所以我尝试按照描述的方式重建它这里

\pgfmathdeclarefunction{bsplinebase}{2}{
\begingroup
\pgfmathparse{#2} 
\edef\arrayvalue{\pgfmathresult}
\pgfmathparse{\tvalues[\arrayvalue]}
\edef\lowvalue{\pgfmathresult}
\pgfmathparse{#2+1} 
\edef\brrayvalue{\pgfmathresult}
\pgfmathparse{\tvalues[\brrayvalue]}
\edef\highvalue{\pgfmathresult}
\pgfmathparse{(and(#1>=\lowvalue, #1<\highvalue))}%
\endgroup
}

测试抽奖:

\pgfplotsset{ymax=1, ymin=0, xmin=0, xmax=500}
\begin{tikzpicture}[samples=1000,scale=0.5]
\begin{axis}[xlabel=$x$,ylabel=$y$] 
  \addplot [mark=none] {bsplinebase(x, 3)}; 
  \addplot [mark=none] {bsplinebase(x, 4)}; 
\end{axis}
\end{tikzpicture}

不管怎样,我File ended while scanning use of \pgfflt@readlowlevelfloat.每次都得到了。
我没有任何想法。如何使用给定的一组 t 值实现类似于上面的可视化并显示 N_i^k ?


(图片来源:我校计算机图形学讲座材料)


编辑:我根据 Christian 的回答修改了我的解决方案,它适用于基本函数。下一步是让递归调用工作。所以我这样做了:

\def\tvalues{{53,125,172,248,286,338,415}}

% N_i^1(t), param 1: t, param 2: i  
\pgfmathdeclarefunction{bsplinebase}{2}{\pgfmathparse{and(#1>=\tvalues[#2], #1<\tvalues[#2+1])}}

% N_i^k(t), param 1: t, param 2: i, param 3: k with k > 1
\pgfmathdeclarefunction{bsplinehigh}{3}{ %
    \pgfmathparse{ %
        ((#1-\tvalues[#2])/(\tvalues[#2+#3-1]-\tvalues[#2]))*bspline(#1,#2,#3-1)+((\tvalues[#2+#3]-#1)/(\tvalues[#2+#3]-\tvalues[#2+1]))*bspline(#1,#2+1,#3-1)%
    }
}
% N_i^k(t), param 1: t, param 2: i, param 3: k
\pgfmathdeclarefunction{bspline}{3}{\pgfmathparse{ifthenelse(#3 <= 1, bsplinebase(#1, #2), bsplinehigh(#1, #2, #3))}}

调用基本相同(\addplot [mark=none] {bspline(x, 3, 1)};对于 x、4、1 也一样),因此它应该只使用 bsplinebase 函数,因为第三个参数应该让 ifthenelse 使用第一个选择,即 bsplinebase,而不是 bsplinehigh。
我还尝试bsplinehigh用常数替换 -logic,在这种情况下它成功构建了 pdf,但没有图,甚至没有轴。

显示的第一个错误Package PGF Math Error: You've asked me to divide '-247.0' by '0.0', but I ca{53,125,172,248,286,338,415}[3+1]))*bspline(1,3+1,1-1)'). \addplot [mark=none] {bspline(x,3,1)};似乎已经损坏。此外,他甚至不应该陷入必须进行划分的情况,如上所述。

为什么这不起作用?它应该与以前完全相同,但 ifthenelse 不能按预期工作。我唯一的猜测是,即使没有使用 else-case,它也会得到评估,但我不确定这是否真的如此。如果是的话,我需要一种方法来防止这种情况。
编辑:这个问题暗示可能正如我猜测的那样。


阅读上述问题的答案后,我尝试像这样解决评估问题:

\def\tvalues{{53,125,172,248,286,338,415}}

% N_i^1(t), param 1: t, param 2: i  
\pgfmathdeclarefunction{bsplinebase}{2}{\pgfmathparse{and(#1>=\tvalues[#2], #1<\tvalues[#2+1])}}

% N_i^k(t), param 1: t, param 2: i, param 3: k with k > 1
\pgfmathdeclarefunction{bsplinehigh}{3}{%
    \pgfmathparse{%
        (((#1-\tvalues[#2])/(\tvalues[#2+#3-1]-\tvalues[#2]))*bspline(#1,#2,#3-1)+((\tvalues[#2+#3]-#1)/(\tvalues[#2+#3]-\tvalues[#2+1]))*bspline(#1,#2+1,#3-1))%
    }
}
% N_i^k(t), param 1: t, param 2: i, param 3: k
\pgfmathdeclarefunction{bspline}{3}{%
    \ifnum#3<2\pgfmathparse{bsplinebase(#1,#2)}\else\pgfmathparse{bsplinehigh(#1,#2,#3)}\fi%
}

这再次适用于我的 basespline 案例,所以现在我添加了\addplot [mark=none] {bspline(x,0,2)};。然后,下一个问题:
Missing = inserted for \ifnum. \addplot [mark=none] {bspline(x,0,2)};
我不知道问题是什么。

编辑:这个问题有同样的问题,现在我们越来越接近了!

答案1

主要困难似乎是 TeX 浮点单元的弱点 —— 它似乎无法处理数组语法。通过有效方法停用它use fpu=false

请注意,您的代码不包含任何domain参数——您的x参数是使用默认域采样的-5:5

添加两者+一些样式更改(我在试验代码片段时忘记删除了)会导致

\documentclass{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.13}

\begin{document}
\def\tvalues{{53,125,172,248,286,338,415}}
\pgfmathdeclarefunction{bsplinebase}{2}{\pgfmathparse{and(#1>=\tvalues[#2], #1<\tvalues[#2+1])}}

\begin{tikzpicture}[samples=1000]
\begin{axis}[
    use fpu=false,
    xlabel=$x$,ylabel=$y$,
    ymax=2, ymin=0, xmin=0, xmax=500,
    domain=0:500,
    ] 
  \addplot [mark=none] {bsplinebase(x, 3)}; 
  \addplot [mark=none] {bsplinebase(x, 4)}; 
\end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

在 Christian 的帮助和大量的搜索下,我成功让它工作了!

定义:

\def\tvalues{{53,125,172,248,286,338,415}}

% N_i^1(t), param 1: t, param 2: i  
\pgfmathdeclarefunction{bsplinebase}{2}{\pgfmathparse{and(#1>=\tvalues[#2], #1<\tvalues[#2+1])}}

% N_i^k(t), param 1: t, param 2: i, param 3: k with k > 1
\pgfmathdeclarefunction{bsplinehigh}{3}{%
    \pgfmathparse{%
        (((#1-\tvalues[#2])/(\tvalues[#2+#3-1]-\tvalues[#2]))*bspline(#1,#2,#3-1)+((\tvalues[#2+#3]-#1)/(\tvalues[#2+#3]-\tvalues[#2+1]))*bspline(#1,#2+1,#3-1))%
    }
}
% N_i^k(t), param 1: t, param 2: i, param 3: k
\pgfmathdeclarefunction{bspline}{3}{%
    \pgfmathparse{#3>1 ? 0 : 1}%
    \ifnum\pgfmathresult=1\pgfmathparse{bsplinebase(#1,#2)}\else\pgfmathparse{bsplinehigh(#1,#2,#3)}\fi%
}

然后呼叫:

\pgfplotsset{ymax=2, ymin=0, xmin=1,xmax=500}
\begin{tikzpicture}[samples=1000]
\begin{axis}[
    use fpu=false,
    xlabel=$x$,ylabel=$y$,
    ymax=2, ymin=0, xmin=1, xmax=500,
    domain=1:500,
    ] 
    \addplot [mark=none] {bspline(x,3,1)}; 
    \addplot [mark=none] {bspline(x,4,1)};
    \addplot [mark=none] {bspline(x,0,2)};  
    \addplot [mark=none] {bspline(x,4,2)};
    \addplot [mark=none] {bspline(x,1,3)};  
\end{axis}
\end{tikzpicture}

相关内容