【问题标题】:Constructing piecewise symbolic function in Matlab在 Matlab 中构造分段符号函数
【发布时间】:2010-09-10 18:02:50
【问题描述】:

我正在尝试在 Matlab 中生成分段符号函数。它必须是象征性的原因是我希望能够在之后集成/区分函数和/或插入实际值。我有以下功能:

x^3/6   ->   0 < x <= 1
(1/6)*(-3*x^3+12*x^2-12x+4)   ->   1 < x <= 2
(1/6)*(3*x^3-24*x^2+60x-44)   ->   2 < x <= 3
(1/6)*(4-x)^3   ->   3 < x <= 4
0   ->   otherwise

比如我想把这个函数放在一个变量中(比如说f)然后调用

int(diff(f, 1)^2, x, 0, 4) % numbers could be different

并获得(标量)结果 2/3。

我尝试了各种方法,包括分段() 函数和符号比较,但没有任何效果......你能帮忙吗? :-)

【问题讨论】:

    标签: matlab symbolic-math piecewise


    【解决方案1】:

    一种选择是使用heaviside 函数使每个方程在其给定范围之外等于零,然后将它们全部加到一个方程中:

    syms x;
    f = (heaviside(x)-heaviside(x-1))*x^3/6 + ...
        (heaviside(x-1)-heaviside(x-2))*(1/6)*(-3*x^3+12*x^2-12*x+4) + ...
        (heaviside(x-2)-heaviside(x-3))*(1/6)*(3*x^3-24*x^2+60*x-44) + ...
        (heaviside(x-3)-heaviside(x-4))*(1/6)*(4-x)^3;
    double(int(diff(f, 1)^2, x, 0, 4))
    
    ans =
    
        0.6667
    

    另一种选择是对每个子范围内的每个函数执行积分,然后添加结果:

    syms x;
    eq1 = x^3/6;
    eq2 = (1/6)*(-3*x^3+12*x^2-12*x+4);
    eq3 = (1/6)*(3*x^3-24*x^2+60*x-44);
    eq4 = (1/6)*(4-x)^3;
    total = int(diff(eq1, 1)^2, x, 0, 1) + ...
            int(diff(eq2, 1)^2, x, 1, 2) + ...
            int(diff(eq3, 1)^2, x, 2, 3) + ...
            int(diff(eq4, 1)^2, x, 3, 4)
    
    total =
    
    2/3
    

    更新:

    尽管问题中提到 piecewise 函数不起作用,但 Karan's answer 建议它起作用,至少在较新的版本中是这样。 piecewise 的文档目前说它是在 R2016b 中引入的,但它显然更早出现。我在早在 R2012b 的 Symbolic Math Toolbox 的文档中找到了它,但调用语法与现在不同。我在符号数学工具箱的早期文档中找不到它,但它确实在其他工具箱(例如统计和样条工具箱)中显示为一个函数,这解释了它在问题中的提及(以及为什么它没有为当时的符号方程工作)。

    【讨论】:

    • @Jonas:谢谢。 12x 也需要修复。
    • 关于早在 R2012b,您可能指的是 MuPAD 分段函数,它是与符号数学工具箱不同的接口。对于 SMT,它是在 R2016b 中引入的。很抱歉与工具箱混淆。如果我能回答任何其他问题,请告诉我。
    • @Karan:我现在明白了。它首先出现在 R2012b (MathWorks login required) 的文档中,但仅作为可通过 MuPAD 接口访问的函数,而不是 MATLAB 本身。 R2016b最新版本可以直接从MATLAB中调用。
    【解决方案2】:

    从 R2016b 开始,使用 piecewise 函数

    syms x
    y = piecewise(x<0, -1, x>0, 1)
    
    y =
    piecewise(x < 0, -1, 0 < x, 1)
    

    对于这种情况:

    syms x
    f = piecewise( ...
    0< x <=1, x^3/6, ...
    1 < x <= 2, (1/6)*(-3*x^3+12*x^2-12*x+4), ...
    2 < x <= 3, (1/6)*(3*x^3-24*x^2+60*x-44), ...
    3 < x <= 4, (1/6)*(4-x)^3, ...
    0)
    
    f =
    piecewise(x in Dom::Interval(0, [1]), x^3/6, x in Dom::Interval(1, [2]), - x^3/2 + 2*x^2 - 2*x + 2/3, x in Dom::Interval(2, [3]), x^3/2 - 4*x^2 + 10*x - 22/3, x in Dom::Interval(3, [4]), -(x - 4)^3/6, 0)
    
    int(diff(f, 1)^2, x, 0, 4)
    ans =
    2/3
    

    【讨论】:

    • 对不赞成票的解释会很有帮助,因为这是在 Symbolic Math Toolbox 中创建分段函数的推荐方法。
    • 我猜反对票是因为您的旧示例根本不符合问题;您的新示例应该可以解决这个问题。此外,我的回答中的更新可能很有趣。人们可能投了反对票,因为该问题特别提到了piecewise 不起作用,实际上它在被问到时并没有,但现在正如你所展示的那样。
    • 很公平。我希望我编辑的答案是有用的。很高兴回答任何其他问题。
    猜你喜欢
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    相关资源
    最近更新 更多