2010-09-10 28 views
11

Próbuję generować symboliczną funkcję w Matlab. Powód, dla którego musi być symboliczny, polega na tym, że chcę móc później zintegrować/zróżnicować funkcję i/lub wstawić rzeczywiste wartości. Mam następującą funkcję:Konstruowanie operacji symbolicznych w 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 

Na przykład chcę umieścić tę funkcję w zmiennej (powiedzmy, f), a następnie zadzwonić

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

i uzyskać (skalarne) skutkować 2/3 .

Próbowałem różnych rzeczy, włączając w to funkcję pieceswise() i porównania symboliczne, ale nic nie działało ... czy możesz pomóc? :-)

Odpowiedz

9

Jedną z opcji jest użycie funkcji heaviside aby każde równanie równe zeru poza jego danym zakresie, a następnie dodać je wszystkie razem w jednym równaniem:

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 

Inną alternatywą jest wykonać swoją integrację dla każdej funkcji na każdym podzakresie następnie dodać wyniki:

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 

UPDATE:

Chociaż wspomniano w pytaniu, że funkcja piecewise nie działa, Karan's answer sugeruje, że tak, przynajmniej w nowszych wersjach. Dokumentacja dla piecewise mówi obecnie, że została wprowadzona w R2016b, ale była wyraźnie obecna znacznie wcześniej. Znalazłem go w dokumentacji dla Symbolic Math Toolbox już w R2012b, ale składnia wywołania była inna niż jest teraz. Nie mogłem znaleźć go we wcześniejszej dokumentacji dla Symbolic Math Toolbox, ale pojawił się on jako funkcja w innych skrzynkach narzędziowych (takich jak Statistics i Spline Toolboxes), co wyjaśnia jego wzmiankę w pytaniu (i dlaczego nie pracować dla równań symbolicznych w tym czasie).

+0

Powinno być 60 * x. – Jonas

+0

@ Jonas: Dzięki. "12x" również trzeba było naprawić. – gnovice

+0

Odnośnie _as daleko wstecz jako R2012b_, możesz odwoływać się do funkcji fragmentacji MuPAD, która jest innym interfejsem niż przy przyborniku Symbolic Math. Dla SMT została wprowadzona w R2016b. Przepraszam za zamieszanie za pomocą narzędzi. Daj mi znać, jeśli mogę odpowiedzieć na wszelkie inne pytania. –

3

Zaczynając R2016b użyj piecewise funkcję

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

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

W tym przypadku:

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 
+0

Pomocne byłyby wyjaśnienia dotyczące przyczyn, ponieważ jest to zalecana metoda tworzenia funkcji odcinkowych w programie Symbolic Math Toolbox. –

+0

Zgaduję, że spadły oceny, ponieważ twój stary przykład w ogóle nie pasował do pytania; twój nowy przykład powinien temu zaradzić. Również aktualizacja w mojej odpowiedzi może być interesująca. Ludzie mogą mieć obniżone oceny, ponieważ w pytaniu wyraźnie mówi się o "częściowym" niedziałającym, co w rzeczywistości nie miało miejsca w momencie, w którym zostało zadane, ale robi to teraz, co widać. – gnovice

+0

Wystarczająco fair. Mam nadzieję, że moja zredagowana odpowiedź jest przydatna. Chętnie odpowiem na wszelkie inne pytania. –