如何在MATLAB中创建分段内联函数?

Sco*_*ott 7 matlab inline function piecewise

我在MATLAB中有一个函数,它将另一个函数作为参数.我想以某种方式定义一个可以传入的分段内联函数.这在MATLAB中是否可行?

编辑:我想表达的功能是:

f(x) = { 1.0,  0.0 <= x <= 0.5,
         -1.0, 0.5 < x <= 1.0

where 0.0 <= x <= 1.0
Run Code Online (Sandbox Code Playgroud)

小智 12

你确实定义了一个带有三个断点的分段函数,即[0,0.5,1].但是,您尚未在中断之外定义函数的值.(顺便说一句,我在这里使用了"break"这个术语,因为我们确实定义了一个简单形式的样条,一个分段常数样条.我也可能使用了术语knot,这是样条世界中的另一个常用词. )

如果您完全知道永远不会评估[0,1]之外的函数,那么就没有问题了.因此,只需在x = 0.5处定义具有ONE断点的分段函数.定义像你这样的分段常量函数的简单方法是使用逻辑运算符.因此,测试(x> 0.5)返回一个常数,0或1.通过缩放和转换结果,可以很容易地生成一个符合您希望的函数.

constfun = @(x) (x > 0.5)*2 - 1;
Run Code Online (Sandbox Code Playgroud)

内联函数执行类似的操作,但与匿名函数相比,内联函数非常慢.我强烈建议使用匿名表格.作为测试,试试这个:

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.
Run Code Online (Sandbox Code Playgroud)

是的,内联函数比匿名表单花了更多的时间来执行.

我在这里使用的简单分段常数形式的一个问题是当你有更多的断点时很难扩展.例如,假设您希望定义一个函数,该函数根据点落入的间隔而采用三个不同的值?虽然这可以通过创造性地使用测试,小心地移动和缩放它们来完成,但它可能会变得令人讨厌.例如,如何定义返回的分段函数

-1 when x < 0,
2 when 0 <= x < 1,
1 when 1 <= x
Run Code Online (Sandbox Code Playgroud)

一种解决方案是使用单位Heaviside函数.首先,定义一个基本单位Heaviside函数.

H = @(x) (x >= 0);
Run Code Online (Sandbox Code Playgroud)

我们的分段函数现在来自H(x).

P = @(x) -1 + H(x)*3 + H(x-1)*(-1);
Run Code Online (Sandbox Code Playgroud)

看到P(x)有三个部分.第一个术语是第一个断点以下x发生的情况.然后我们添加一个在零以上生效的片段.最后,第三部分在x == 1之上增加了另一个偏移.很容易绘制.

ezplot(P,[-3,3])
Run Code Online (Sandbox Code Playgroud)

从这个开始就可以轻松生成更复杂的样条.我称之为construct再次构造一个样条曲线.真的,这是我们可能领导的地方.事实上,这是领先的地方.样条曲线是一种分段函数,在结点或断点列表中小心地绑在一起.特别是样条曲线通常具有指定的连续性顺序,因此,例如,三次样条曲线在断点处将是两次可微分(C2).还有分段三次函数,它们只是C1函数.我在所有这一点上的观点是我已经描述了一个简单的起点来形成任何分段函数.它对多项式样条函数很有效,尽管选择这些函数的系数可能需要一点点数学.

创建此函数的另一种方法是显式分段多项式.在MATLAB中,我们有一个鲜为人知的函数mkpp.试试这个......

pp = mkpp([0 .5 1],[1;-1]);
Run Code Online (Sandbox Code Playgroud)

如果你是splines工具箱,那么fnplt会直接为你绘制这个.假设您没有TB,请执行以下操作:

ppfun = @(x) ppval(pp,x);
ezplot(ppfun,[0 1])
Run Code Online (Sandbox Code Playgroud)

回顾一下mkpp的调用,毕竟它很简单.第一个参数是曲线中的断点列表(作为ROW向量).第二个参数是一个COLUMN向量,其中曲线将在断点之间的这两个定义的间隔中采用分段常量值.

几年前我发布了另一个选项,piecewise_eval.它可以从MATLAB Central文件交换中下载.这是一个允许用户将分段函数纯粹指定为断点列表以及这些断点之间的功能块的函数.因此,对于在x = 0.5处具有单个中断的函数,我们将执行此操作:

fun = @(x) piecewise_eval(x,0.5,{1,-1});
Run Code Online (Sandbox Code Playgroud)

看到第三个参数提供了每个段中使用的值,尽管这些段不必是纯粹的常量函数.如果你希望函数返回一个超出感兴趣区间的NaN,这也很容易实现.

fun = @(x) piecewise_eval(x,[0 0.5 1],{NaN,1,-1,NaN});
Run Code Online (Sandbox Code Playgroud)

我在所有这些相当冗长的偏移中的观点是理解分段函数是什么,以及在MATLAB中构建一个函数的几种方法.


Edr*_*ric 5

遗憾的是,MATLAB没有三元运算符可以使这种事情变得更容易,但是为了稍微扩展gnovice的方法,你可以创建一个匿名函数,如下所示:

fh = @(x) ( 2 .* ( x <= 0.5 ) - 1 )
Run Code Online (Sandbox Code Playgroud)

通常,匿名函数比内联函数对象更强大,并允许您创建闭包等.