Przekształcanie wyrażeń matematycznych

Wzory skróconego mnożenia i rozkład wielomianów na czynniki

Przykład 1: szkolne wzory

Podstawowe polecenia wykonujące czynności równoważne stosowaniu szkolnych wzorów to Factor (rozłóż na czynniki) i Expand (wymnóż wszystkie nawiasy).

w1= 6x^2+x y +-y^2-10 x z - 5 y z

w1a=Factor[w1]

Aby ustalić, czy dwa wyrażenia są identyczne, odejmujemy je od siebie i upraszczamy. Spodziewany wynik to ZERO.

w1-w1a

Simplify[%]

Alternatywnie, możemy je podzielić i sprawdzić czy wychodzi 1.

w1/w1a

Simplify[%]

Mathematica pozwala także bezpośrednio sprawdzić równość:

w1==w1a

Simplify[%]

Zwracam uwagę na fakt, iż ustalenie czy dwa wyrażenia bardziej skomplikowane niż wielomiany są identyczne jest w ogólności problemem niedecydowalnym. Oznacza to, że zawsze możemy natrafić na przykład, z którym Mathematica sobie w powyższy sposoób nie poradzi.

Z łatwością produkujemy wzory, które staja się niemożliwe do objęcia przez człowieka:

Manipulate[Expand[(a+b+c)^n],{n,0,12,1}]

Ale ich uproszczenie nie stanowi problemu dla komputera:

w2=128 (a^8)-192 (a^7) b-224 (a^6) (b^2)+784 (a^5) (b^3)-840 (a^4) (b^4)+476 (a^3) (b^5)-154 (a^2) (b^6)+27 a (b^7)-2 (b^8)+1344 (a^7) c-1344 (a^6) b c-3024 (a^5) (b^2) c+6720 (a^4) (b^3) c-5460 (a^3) (b^4) c+2268 (a^2) (b^5) c-483 a (b^6) c+42 (b^7) c+6048 (a^6) (c^2)-3024 (a^5) b (c^2)-15120 (a^4) (b^2) (c^2)+22680 (a^3) (b^3) (c^2)-13230 (a^2) (b^4) (c^2)+3591 a (b^5) (c^2)-378 (b^6) (c^2)+15120 (a^5) (c^3)-37800 (a^3) (b^2) (c^3)+37800 (a^2) (b^3) (c^3)-14175 a (b^4) (c^3)+1890 (b^5) (c^3)+22680 (a^4) (c^4)+11340 (a^3) b (c^4)-51030 (a^2) (b^2) (c^4)+31185 a (b^3) (c^4)-5670 (b^4) (c^4)+20412 (a^3) (c^5)+20412 (a^2) b (c^5)-35721 a (b^2) (c^5)+10206 (b^3) (c^5)+10206 (a^2) (c^6)+15309 a b (c^6)-10206 (b^2) (c^6)+2187 a (c^7)+4374 b (c^7);

Factor[w2]

Mniej znany wzór skróconego mnożenia, pozwala na przekształcanie wyrażeń typu:

w3=(a^7+b^7)/(a+b)

w3a=Factor[w3]

Niestety, moje próby powrotu do oryginalnej postaci zakończyły się niepowodzeniem pomimo że, jest ewidentnie prostsza:

Simplify[w3a]

FullSimplify[w3a]

LeafCount[w3]

LeafCount[w3a]

ByteCount[w3]

ByteCount[w3a]

Porównajmy jeszcze działanie polecenia Expand i Cancel (skróć identyczne składniki w liczniku i mianowniku):

Expand[w3]

Cancel[w3]

Czasem jest potrzeba wydobycia licznika lub mianownika ułamka. Służą do tego polecenia Numerator (licznik) i Denominator (mianownik):

Numerator[w3]

Denominator[w3]

Przykład 2: rozłóż na czynniki wielomian
(x^4)+1

w4=x^4+1

Samo polecenie Factor nie wystarcza w tym przypadku:

Factor[w4]

FactorSquareFree[w4]

Równanie w4==0 nie posiada rozwiązań rzeczywistych:

NSolve[w4==0,x]

Solve[w4==0,x]

Reduce[w4==0,x]

Aby uzyskać wyniki w postaci jawnej (część rzeczywista i urojona osobno), należy użyć ComplexExpand:

ComplexExpand[%%]

Rozkład wyrażenia w dziedzinie rzeczywistej zawsze jest możliwy. Potrzebny jest np: do całkowania funkcji wymiernych z takim właśnie mianownikiem. Aby go otrzymać, musimy roszerzyć listę ,,dozwolonych’’ symboli. Jak widać po wyniku Solve należą do nich Sqrt[2] oraz jednostka urojona (I). Rozszerzenie o jeden z nich, lub oba daje różne rozkłady na czynniki:

Factor[w4,Extension->Sqrt[2]]

Factor[w4,Extension->I]

Factor[w4,Extension->{I,Sqrt[2]}]

Podobnie możemy rozłożyć ine tego typu wyrażenia:

Factor[x^6+1,Extension->Sqrt[3]]

Factor[x^2-Pi,Extension->Sqrt[Pi]]

Przykład 3: rozłóż na czynniki wielomian
2 (x^3)+3 (x^2)-x-1

w5=-1-x+3 (x^2)+2 (x^3)

Factor[w5]

Solve[w5==0,x]

Factor[w5,Extension->{Sqrt[5]}]

Przykład 4: rozłóź na czynniki wielomian:
(x^3)+(x^2)-x+3

w6=x^3+x^2-x+3

Factor[w6]

Solve[w6==0,x]

Reduce[w6==0,x,Reals]

Factor[w6,Extension->Root[3-#1+((#1)^2)+((#1)^3)&,1]]

Expand[%]

Simplify[%]

Factor[w6,Extension->Root[3-#1+((#1)^2)+((#1)^3)&,1]]/.Root[3-#1+((#1)^2)+((#1)^3)&,1]->r

Simplify[%]

Expand[%]

Factor[w6,Extension->{2^(2/3),(((23-3 (Sqrt[57])))^(1/3))}]

FullSimplify[%]

Nie zawsze procedura faktoryzacji jest jednoznaczna. Poniżej bardziej skomplikowany przypadek. Rozłóżmy powyższy wielomian, rozszerzając listę symboli o wszystkie 3 pierwiastki równania 3 stopnia:

Factor[w6,Extension->{Root[3-#1+((#1)^2)+((#1)^3)&,1],Root[3-#1+((#1)^2)+((#1)^3)&,2],Root[3-#1+((#1)^2)+((#1)^3)&,3]}]

Dostajemy bardzo długie wyrażenie:

Expand[%]

Po jego uproszczeniu nie otrzymaliśmy wyjściowego równania!

FullSimplify[%]

Expand[%]

Żadne zabiegi nie doprowadzają równania do pierwotnej, prostej postaci :

FullSimplify[%]

w5a=Expand[%]

Dopiero obliczenia numeryczne wskazują, że powyższe wyrażenie jest tożsamościowo równe zadanemu wielomianowi:

N[w5a]

N[w5a,128]

Chop[%]

Rationalize[%]

Z powyższego wynika, że np:

tozsamosc=Root[165762298492416+4352087232 #1-63480 ((#1)^2)+((#1)^3)&,3]==-12696 ((Root[-9+3 #1+((#1)^2)+((#1)^3)&,3])^2)

N[tozsamosc]

Simplify[tozsamosc]

FullSimplify[tozsamosc]

Rozkład na ułamki proste

Przykład 1: rozłóż na ułamki proste wyrażenie wymierne
(((x^3)+x+1)/((x^2)-1))

W licznych zastosowaniach musimy dokonać rozkładu funkcji wymiernej (wielomian/wielomian) na ułamki proste. Jest to np. podstawą szkolnego, liczącego 300 lat, algorytmu ich całkowania. Służy do tego polecenie Apart:

(x^3 + x + 1)/(x^2 - 1)

Apart[%]

(x^3+x+1)/(x^2+1)

Apart[%]

Operacja odwrotna to sprowadzenie do wspólnego mianownika, wykonywane poleceniem Together:

Together[%]

Together[1/x+1/y]

Przykład 2: rozłóż na ułamki proste wyrażenie wymierne
(x/((x^4)+1))

Przy rozkładzie na ułamki proste stykamy się z takim samym problemem co przy faktoryzacji wielomianów. W większości przypadków, aby uzyskać spodziewany rezultat, musimy dodać do liczb wymiernych symbole odpowiadające pierwiastkom wielomianów, czyli Sqrt oraz Root:

Apart[x/(1+x^4)]

Apart[x/(1+x^4),Extension->Sqrt[2]]

Factor[x/(1+x^4),Extension->Sqrt[2]]

Apart[%]

Tożsamości trygonometryczne i potęgowe

Podstawowe szkolne wzory trygonometryczne

Polecenie Expand nie działa na funkcje trygonometryczne (aby wpisać α naciśnij ESC a ESC ):

Cos[α+β]//Expand

Powyżej zastosowałem notację postfiksową. Podwojony ukośnik // oznacza: zastosuj polecenie do wyrażenia poprzedzającego. Jest to notacja szczególnie wygodna przy pracy interaktywnej, kiedy to o konieczności uproszczenia wyrażenia dowiadujemy się zwykle już po jego wpisaniu.

Cos[Pi] (* wywołanie funkcji za pomocą nawiasów *)

Pi //Cos (* wywołanie w notacji posfiksowej *)

Cos@Pi (* wywołanie funkcji w notacji prefiksowej *)

Ogólna zasada tworzenia poleceń operujących na wyrażeniach trygonometrycznych polega na dodaniu do zwykłej postaci przedrostka Trig.
Na przykład Expand (stosowany głównie do wielomianów) zamieniamy na TrigExpand:

Cos[α+β]//TrigExpand (* kosinus sumy *)

Sin[α-β]//TrigExpand (* sinus różnicy *)

Cos[2α]//TrigExpand (* kosinus podwojonego kąta *)

Sin[2α]//TrigExpand (* sinus podwojonego kąta *)

Niektóre najprostsze przekształcenia wykonywane są automatycznie:

Sin[3 Pi/2-α]

Bardziej złożone wymagają użycia TrigExpand:

Cos[Pi/6-α]

TrigExpand[%]

Cos[α+1]//TrigExpand

3 Cos[α+2]//TrigExpand

Poleceniem odwrotnym jest TrigFactor:

%//TrigFactor

Niestety, jest ono znacznie ,,słabsze’’ niż dla wielomianów:

2 Cos[α]+Sin[α]//TrigFactor

Dobry student bez problemu obliczy, że powyższe wyrażenie jest równe:

Sqrt[5]Sin[α+ArcTan[2]]

TrigExpand[%]

2 Cos[α]+Sin[α]//TrigReduce

TrigFactor[Cos[2α]-Sin[α]]

Cos[12 x]//TrigExpand

Przypominam, że szkolna skrótowa notacja (sin^2)x+(cos^2)x jest niedpouszczalna.

Cos^2[x]+Sin^2[x]

Prawidłowy zapis to Sin[x]^2+Cos[x]^2:

Cos[x]^2+Sin[x]^2

TrigFactor[%]

Konwersja funkcji trygonometrycznych na eksponenty i odwrotnie

Część studentów już spotkała się zapewne z wykładniczą postacią funkcji trygnometrycznych. Aby ją uzyskać stosujemy polecenie TrigToExp:

Sin[x]

TrigToExp[%]

Podręcznikowa postać to zwykle:

(Exp[I x]-Exp[-I x])/(2I)

%-%%

Simplify[%]

Podobnie, możemy eksponentę skonwertować na funkcje trygonometryczne poleceniem ExpToTrig:

Exp[x]

ExpToTrig[%]

E^(I x) //ExpToTrig

Aczkolwiek powyższe przekształcenia mogą wyglądać obco dla osób nie obeznanych z liczbami zespolonymi, umiejętność operowania nimi jest kluczowa, gdyż Mathematica losowo produkuje funkcje trygonometryczne w postaci standardowej lub wykładniczej, nawet gdy wynik jest de facto rzeczywisty.

Przekształcanie wyrażeń logarytmicznych i potęgowych

Mathematica nie upraszcza wyrażeń logarytmicznych automatycznie:

Log[x^3]

Aby zastosować szkolne reguły przekształcania logarytmów musimy użyć polecenia PowerExpand. Nazwa pochodzi od instrukcji potęgowania:

x^7

FullForm[x^7]

TreeForm[Sqrt[x]^3]

1/x//FullForm

Jak widać powyżej wszystkie potęgowania, w tym odwrotności i pierwiastki, są wewnętrznie konwertowane na polecenie Power.

Aby uprościć wyrażenia zawierające potęgowanie i logarytmy, stosujemy PowerExpand:

PowerExpand[Log[x^3]]

Log[a b^2/c]

PowerExpand[%]

Podobnie postępujemy z potęgowaniem:

(x^3)^n/x

PowerExpand[%]

Jako ciekawostę podaję, że wszystkie funkcje elementarne można uzyskać posługując się wyłącznie funkcjami Exp i Log i liczbą zero, na przykład:

Exp[E^(Log[Log[x]]-Log[Exp[0]+Exp[0]])]

Exp[x]//TreeForm

Log[2,x]//TreeForm

Stosowanie założeń

Przykład 1: oblicz (Sqrt[(a^2)])

Każdy wie, że pierwiastek z a do kwadratu to wartość bezwzględna z a. Dlaczego Mathematica tego nie wie:

FullSimplify[Sqrt[a^2]]

Powyższe nie jest manifestacją nieudolności programu. Jest to ilustracja podstawowego faktu dotyczącego obliczeń symbolicznych: każdy symbol jest traktowany jako oznaczenie pewnej liczby zespolonej!

Większość za szkolnych tożsamości dotyczy tylko i wyłącznie liczb rzeczywistych i nie zachodzi dla liczb zespolonych.

Sqrt[a^2]==Abs[a]

Sqrt[a^2]==Abs[a]/.a->1

Sqrt[a^2]==Abs[a]/.a->0

Sqrt[a^2]==Abs[a]/.a->-1

Sqrt[a^2]==Abs[a]/.a->I

FindInstance[Sqrt[a^2]!=Abs[a],a]

FindInstance[Sqrt[a^2]!=Abs[a],a,Reals]

Ponieważ często chodzi nam o wyniki rzeczywiste (np. w matematyce szkolnej) lub nawet dodatnie (w fizyce) musimy umieć posługiwać się poleceniami zmieniającymi znaczenie symboli, które są traktowane jako liczby zespolone, na symbole interpretowane jako liczby rzeczywiste.

Zalecany sposób postępowania jest następujący:
1) pozwalamy Mathematice wykonywać wszystkie obliczenia w domenie zepolonej
2) upraszczamy wynik końcowy zakładając, że symbole są rzeczywiste 

Odwrotna kolejność zwykle skutkuje ,,interferencją’’ pomiędzy algorytmami, aczkolwiek w konkretnym przypadku należy to ustalić metodą prób i błędów.

Próbujemy uprościć wzór bez założeń:

Simplify[Sqrt[a^2]]

Na koniec ,,doprecyzujemy’’, że a ma być większe od zera:

Refine[%,a>0]

Zwracam uwagę, że użycie znaku mniejszości automatycznie oznacza, iż dany symbol jest rzeczywisty! W domenie liczb zespolonych porządek nie istnieje - nie można określić, która liczba zepolona jest większa.

Simplify[Sqrt[a^2]]

Refine[%,a∈Reals]

Sqrt[R^3]/R^2

Simplify[%,R>0]

PowerExpand[%%]

Sqrt[a^2-2 a b+b^2]/(a-b)

Refine[%,a>0&&b>0]

Refine[%,a>b]

Simplify[%,a>b]

Przyklad 2: oblicz (a^4)+(b^4) jeżeli a+b=1 oraz (a^2)+(b^2)=7

Simplify[a^4+b^4,Assumptions->a+b==1&&a^2+b^2==7]

Simplify[a^4+b^4,Assumptions->{a+b==1,a^2+b^2==7}]

$Assumptions

$Assumptions=a+b==1&&a^2+b^2==7

Simplify[a^4+b^4]

Assuming[a+b==1&&a^2+b^2==7,Simplify[a^4+b^4]]

Przykład 3: oblicz Cos[n π] + (((-1))^(n+3)) jeżeli n jest liczbą całkowitą

Cos[n Pi]+(-1)^(n+3)

FullSimplify[%]

Simplify[%,n∈Integers]

Simplify[Cos[n Pi]+(-1)^(n+3),Integers]

Przykład 4: oblicz moduł liczby zespolonej R + i ω L + 1/(i ω C)

Na pracowni elektronicznej potrzebne są wyrażenia typu:

Abs[R+I ω L +1/I/ω/Cc]

gdzie R, L, C  a także ω są liczbami rzeczywistymi większymi od zera. Uproszczenie wymaga podania szeregu założeń:

Simplify[%,R∈Reals&&Cc∈Reals&&L∈Reals&&ω∈Reals]

Aby skutecznie upraszczać takie wyrażenia należy użyć ComplexExpand:

ComplexExpand[%]

Polecenie to traktuje wszystkie parametry literowe jako liczby rzeczywiste.