Построение кусочно-символической функции в Matlab - PullRequest
11 голосов
/ 10 сентября 2010

Я пытаюсь сгенерировать кусочно-символическую функцию в 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.

Я пробовал разные вещи, включая кусочную () функцию и символьные сравнения, но ничего не получалось ... Вы можете помочь?: -)

Ответы [ 2 ]

9 голосов
/ 10 сентября 2010

Один из вариантов - использовать функцию 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 функция не работает, ответ Каран предполагает, что она работает, по крайней мере, в новых версиях.Документация для piecewise в настоящее время говорит, что она была представлена ​​в R2016b, но она явно присутствовала намного раньше.Я нашел это в документации для Symbolic Math Toolbox еще в R2012b, но синтаксис вызова был другим, чем сейчас.Я не смог найти его в более ранней документации для Symbolic Math Toolbox, но он обнаружился как функция в других наборах инструментов (таких как наборы инструментов статистики и сплайнов), что объясняет его упоминание в вопросе (и почему это не такработа для символических уравнений в то время).

3 голосов
/ 02 февраля 2017

Начиная с R2016b, используйте функцию кусочно

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
...