Simo K. Kivelä Mitä symbolilaskentaohjelmalta voi odottaa ja mitä ei? Tapaus Mathematica Symbolinen laskenta ei aina toimi, kuten voisi odottaa. Parempi onkin ajatella, että se elää omaa elämäänsä, jolla toki on läheinen suhde matematiikkaan, mutta joka aina toisinaan eroaa matematiikasta. Koska symbolisella laskennalla on ohjelmoinnin luonne, käytän seuraavassa tekstimuotoisia komentoja ja funktioita, vaikka matemaattisen notaation käyttökin olisi mahdollista pienin rajoituksin. Seuraavassa eräitä esimerkkejä. Neljännen asteen yhtälö Talletetaan yhtälö muuttujaan nimeltään yht: In[]:= yht = a x^4 b x^ c x^ d x e 0 Out[]= e d x c x b x a x 4 0 Muodostetaan sijoitussääntö, jonka avulla kertoimille annetaan halutut arvot: In[]:= sij = {a, b 0, c 0, d 0, e } Out[]= {a, b 0, c 0, d 0, e } In[]:= Sijoitetaan kertoimien arvot yhtälöön ja ratkaistaan saatu yhtälö: yht /. sij Out[]= x 4 0 In[4]:= rtk = Solve[yht /. sij, x] Out[4]= {{x }, {x i}, {x i}, {x }} Samaan tulokseen pitäisi tietenkin päästä, jos ensin muodostetaan yhtälön yleinen ratkaisu symbolisin kertoimin ja tähän sijoitetaan kertoimien arvot: In[5]:= ylrtk = Solve[yht, x] Out[5]= x b 4 a b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e /
SymbLask.nb b a 4 c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 b c 8 d a a 4 b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e /, x b 4 a b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 b c 8 d a a 4 b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e /, x b 4 a b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a
SymbLask.nb c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 b c 8 d a a 4 b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e /, x b 4 a b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / b a 4 b c 8 d a a 4 b 4 a c a / c b d a e a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / / a c 9 b c d 7 a d 7 b e 7 a c e 4 c b d a e c 9 b c d 7 a d 7 b e 7 a c e / Yleinen ratkaisu on sangen monimutkainen ja kertoimien arvojen sijoittaminen johtaa virhetilanteeseen:
4 SymbLask.nb In[6]:= ylrtk /. sij Power::infy : Infinite expression 0 encountered. Infinity::indet : Indeterminate expression 0 ComplexInfinity encountered. Power::infy : Infinite expression 0 encountered. Infinity::indet : Indeterminate expression 0 ComplexInfinity encountered. Power::infy : Infinite expression 0 encountered. General::stop : Further output of Power::infy will be suppressed during this calculation. Infinity::indet : Indeterminate expression 0 ComplexInfinity encountered. General::stop : Further output of Infinity::indet will be suppressed during this calculation. Out[6]= {{x Indeterminate}, {x Indeterminate}, {x Indeterminate}, {x Indeterminate}} Arvojen sijoittaminen ja yhtälön ratkaiseminen eivät siis kommutoi, vaikka näin toki pitäisi olla. Jos kertoimia hieman häiritään, niin kaikki toimii kuten pitääkin: In[7]:= eps = 000 000; epssij = {a, b eps, c 0, d 0, e } Out[7]= In[8]:= Out[8]= a, b yht /. epssij, c 0, d 0, e 000 000 x 000 000 x4 0 In[9]:= rtk = Solve[yht /. epssij, x] Out[9]= x 4 000 000 4 000 000 60 000 000 000 000 000 9 768 000 000 000 000 000 000 000 08 / 00 000 000 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 40 000 9 768 000 000 000 000 000 000 000 08 / 0 000 / 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 60 000 000 000 000 000 / 9 768 000 000 000 000 000 000 000 08 / 00 000 000 / 9 768 000 000 000 000 000 000 000 08 /, x 4 000 000 4 000 000 60 000 000 000 000 000 / 9 768 000 000 000 000 000 000 000 08 / 00 000 000
SymbLask.nb 5 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 40 000 9 768 000 000 000 000 000 000 000 08 / 0 000 / 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 60 000 000 000 000 000 9 768 000 000 000 000 000 000 000 08 / 00 000 000 / 9 768 000 000 000 000 000 000 000 08 /, x 4 000 000 4 000 000 60 000 000 000 000 000 / 9 768 000 000 000 000 000 000 000 08 / 00 000 000 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 40 000 9 768 000 000 000 000 000 000 000 08 / 0 000 / 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 60 000 000 000 000 000 9 768 000 000 000 000 000 000 000 08 / 00 000 000 / 9 768 000 000 000 000 000 000 000 08 /, x 4 000 000 4 000 000 60 000 000 000 000 000 / 9 768 000 000 000 000 000 000 000 08 / 00 000 000 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 40 000 9 768 000 000 000 000 000 000 000 08 / 0 000 / 9 768 000 000 000 000 000 000 000 08 / 000 000 000 000 60 000 000 000 000 000 9 768 000 000 000 000 000 000 000 08 / 00 000 000 / 9 768 000 000 000 000 000 000 000 08 / Ratkaisu on jälleen monimutkainen (eikä sen sieventäminenkään auta), mutta laskemalla kymmennumeroinen likiarvo nähdään, mistä on kyse. In[0]:= N[rtk, 0] Out[0]= x.500000000 0 7.000000000 i, x.500000000 0 7.000000000 i, {x.00000050}, {x 0.9999997500}
6 SymbLask.nb Tällä kertaa kertoimien arvojen sijoittaminen yleiseen ratkaisuun antaa laskentatarkuuden rajoissa saman tuloksen: In[]:= rtk = ylrtk /. epssij Out[]= x 4 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / / 4 000 000 000 000 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 /, x 4 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / / 4 000 000 000 000 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 /, x 4 000 000
SymbLask.nb 7 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / / 4 000 000 000 000 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 /, x 4 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 7 768 000 000 000 000 000 000 000 08 000 000 000 000 000 000 000 000 / / 4 000 000 000 000 000 000 4 000 000 000 000 4 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / 7 000 000 000 000 768 000 000 000 000 000 000 000 08 000 000 000 000 / In[]:= N[rtk, 0] Out[]= {x.00000050}, {x 0.9999997500}, x.500000000 0 7.000000000 i, x.500000000 0 7.000000000 i Tarkkoja arvojakin voidaan verrata, kun otetaan huomioon, että eri ratkaisuissa juuret ovat eri
8 SymbLask.nb In[]:= järjestyksessä: x /. rtk[[{4,,, }]] x /. rtk[[{,, 4, }]] // Simplify Out[]= {0, 0, 0, 0} Syöte on hieman monimutkainen, mutta kyseessä on Mathematican syntaksin mukainen tapa laskea eri ratkaisujen juurten erotukset. Sarjan summa Sarja n= on yliharmoninen sarja ja se suppenee. Sijoittamalla yleisessä lausekkeessa eksponentille arvo s = saadaan n summaksi In[4]:= Out[4]= Sum n^s /. s, {n,, Infinity} π 6 Tulos on sama, jos summa lasketaan ensin ja sitten sijoitetaan: In[5]:= Out[5]= Sum n^s, {n,, Infinity} Zeta[s] In[6]:= Sum n^s, {n,, Infinity} /. s Out[6]= In[7]:= Out[7]= π 6 Zeta[] π 6 Mutta jos sijoitetaankin s =, tilanne on toinen: In[8]:= Sum n^s /. s, {n,, Infinity} Out[8]= Sum::div : Sum does not converge. n n= In[9]:= Sum n^s, {n,, Infinity} /. s Out[9]= In[0]:= Zeta[ ] Out[0]= Tätä on oikeastaan pidettävä ohjelmiston virheenä. Arvolla s = sarja ei tietenkään suppene, joten edellinen vaihtoehto on oikein. Jos s > (oikeastaan jos kompleksisen luvun s reaaliosa on > ), sarjan summa on Riemannin zetafunktio (ζ funktio). Tämä voidaan muilla keinoilla määritellä myös arvolla ja tällöin ζ () =. Yleisellä argumentilla s summattaessa tulisi siis Mathematican ilmoittaa myös pätevyysalueen rajoitus.
SymbLask.nb 9 Itseisarvoyhtälö Itseisarvoyhtälön z a = z b ratkaisuksi saadaan lukujen a ja b keskiarvo: In[]:= yht = Abs[z a] Abs[z b] Out[]= Abs[a z] Abs[b z] In[]:= Solve[yht, z] Out[]= Solve::ifun : Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. z a b Varoitus antaa aiheen arvella, että tässä ei ehkä ole koko totuus. Kelpaisihan ainakin mikä tahansa z, jos a = b. Tarkempaan analyysiin päästään toisella komennolla, mutta tulos ei näytä kovin selkeältä: In[]:= rtk = Reduce[yht, z] Out[]= Re[a] < Re[b] && Im[a] < Im[b] && Im[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[z] Re[b] Re[z] ( Im[a] Im[b]) Im[a] Im[b] && Re[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[b] Im[a] > Im[b] && Im[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[z] Re[b] Re[z] ( Im[a] Im[b]) Re[a] Re[b] && Im[a] < Im[b] && Im[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[z] Re[b] Re[z] ( Im[a] Im[b]) Im[a] Im[b] Im[a] > Im[b] && Im[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[z] Re[b] Re[z] ( Im[a] Im[b]) Re[a] > Re[b] && Im[a] < Im[b] && Im[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[z] Re[b] Re[z] ( Im[a] Im[b]) Im[a] Im[b] && Re[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[b] Im[a] > Im[b] && Im[z] Im[a] Im[b] Re[a] Re[b] Re[a] Re[z] Re[b] Re[z] ( Im[a] Im[b]) Tämä on kuitenkin pätevä myös kompleksitapauksessa, jolloin ratkaisu muodostuu pisteitä a ja b yhdistävän janan keskinormaalista: In[4]:= rtk /. {a, b } Out[4]= Re[z] In[5]:= Out[5]= rtk /. {a I, b I} // Simplify Im[z] Re[z]
0 SymbLask.nb Trigonometrinen yhtälö Trigonometrisella yhtälöllä sin(x) = sin x on yksinkertainen ratkaisu x = 5 5 kokonaisluku. Mathematica antaa kuitenkin mutkikkaampaa: n, missä n on In[6]:= yht = Sin[x] Sin[x Pi / 5] Out[6]= Sin[x] Sin π 5 x In[7]:= rtk = Solve[yht, x] Out[7]= x ConditionalExpression ArcTan 4 5 5 5 4 5 0 5 π C[], C[] Integers, x ConditionalExpression π ArcTan 4 5 5 4 5 π C[], 5 0 5 C[] Integers Tehokkaalla sievennyksellä tämä kuitenkin yksinkertaistuu, tosin ei aivan siihen muotoon, mihin käsinlaskija pääsee: In[8]:= FullSimplify[rtk, Element[C[], Integers]] Out[8]= x 5 π ( 5 C[]), x π C[] 5 Eksplisiittinen sievennys onkin usein tarpeen.