您确实定义了一个具有三个断点的分段函数,即在 [0, 0.5, 1] 处。但是,您尚未在中断之外定义函数的值。 (顺便说一句,我在这里使用了术语“中断”,因为我们实际上定义了样条线的简单形式,即分段常量样条线。我可能还使用了术语“结”,它是样条线世界中的另一个常见词。 )
如果你绝对知道你永远不会评估 [0,1] 之外的函数,那么就没有问题。因此,只需定义一个分段函数,在 x = 0.5 处有一个断点。定义像您这样的分段常量函数的简单方法是使用逻辑运算符。因此,测试 (x > 0.5) 返回一个常量,即 0 或 1。通过缩放并转换该结果,可以轻松生成执行您希望的操作的函数。
constfun = @(x) (x > 0.5)*2 - 1;
内联函数执行类似的操作,但内联函数与匿名函数相比非常慢。我强烈建议使用匿名形式。作为测试,请尝试以下操作:
infun = inline('(x > 0.5)*2 - 1','x');
x = 0:.001:1;
tic,y = constfun(x);toc
Elapsed time is 0.002192 seconds.
tic,y = infun(x);toc
Elapsed time is 0.136311 seconds.
是的,内联函数的执行时间比匿名形式要长得多。
我在这里使用的简单分段常数形式的一个问题是,当您有更多断点时,它很难扩展。例如,假设您希望定义一个函数,该函数根据点所处的区间而采用三个不同的值?虽然这也可以通过创造性地使用测试、小心地转移和扩展它们来完成,但它可能会变得很糟糕。例如,如何定义返回的分段函数
-1 when x < 0,
2 when 0 <= x < 1,
1 when 1 <= x
一种解决方案是使用单位亥维赛德功能。首先,定义一个基本单位Heaviside函数。
H = @(x) (x >= 0);
我们的分段函数现在是从 H(x) 导出的。
P = @(x) -1 + H(x)*3 + H(x-1)*(-1);
看到 P(x) 分为三部分。第一项是 x 在第一个断点以下发生的情况。然后我们添加一个在零以上生效的片段。最后,第三部分在上面的 x == 1 中添加了另一个偏移量。它很容易绘制出来。
ezplot(P,[-3,3])
从这里开始可以轻松生成更复杂的样条曲线。我再次将此构造称为样条线。确实,这就是我们可能领先的地方。事实上,这就是结果。样条曲线是一个分段函数,在一系列结点或断点处小心地捆绑在一起。特别是样条曲线通常具有指定的连续性顺序,因此例如,三次样条曲线在断点上将具有两次可微分 (C2)。还有分段三次函数,它们只是 C1 函数。我在这一切中的观点是,我描述了一个形成任何分段函数的简单起点。它对于多项式样条非常有效,尽管选择这些函数的系数可能需要一点数学知识。
创建此函数的另一种方法是作为显式分段多项式。在 MATLAB 中,我们有一个鲜为人知的函数 mkpp。试试这个...
pp = mkpp([0 .5 1],[1;-1]);
如果您有样条工具箱,那么 fnplt 将直接为您绘制此图。假设您没有结核病,请执行以下操作:
ppfun = @(x) ppval(pp,x);
ezplot(ppfun,[0 1])
回顾一下 mkpp 调用,毕竟还是比较简单的。第一个参数是曲线中的断点列表(作为 ROW 向量)。第二个参数是一个 COLUMN 向量,其中曲线在这两个定义的中断间隔内将呈现分段常数值。
几年前我发布了另一个选项,分段评估。它可以从 MATLAB Central 文件交换下载。该函数允许用户将分段函数纯粹指定为断点列表,以及这些断点之间的功能片段。因此,对于在 x = 0.5 处有一个断点的函数,我们将这样做:
fun = @(x) piecewise_eval(x,0.5,{1,-1});
请注意,第三个参数提供了每个段中使用的值,尽管这些段不必是纯粹的常量函数。如果您希望函数返回感兴趣区间之外的 NaN,这也很容易实现。
fun = @(x) piecewise_eval(x,[0 0.5 1],{NaN,1,-1,NaN});
在所有这些相当冗长的游览中,我的目的是了解什么是分段函数,以及在 MATLAB 中构建分段函数的几种方法。