Simo K. Kivelä / 28.04.2003

Mathematica numeerisena ja symbolisena laskimena

•Mitä laskentaohjelmalta voi odottaa?

Periaatteessa interaktiivinen symbolinen laskentaohjelma on kuin laajennettu taskulaskin: voidaan laskea numeerisia arvoja lausekkeille, muokata (sieventää eri tavoin, derivoida, integroida jne.) symbolisia, ts. kirjaimia sisältäviä lausekkeita, laatia erilaisia graafisia esityksiä (funktioiden kuvaajia, tilastoja yms.), kirjoittaa ohjelmakoodeja ohjelman omalla kielellä, tallettaa syötteet ja tulosteet dokumentiksi, joka voidaan varustaa selittävillä teksteillä, jne. Dokumentti voidaan tulostaa paperille tai muuntaa www-sivuiksi. Tämä esitys on juuri tällainen dokumentti.

Laskentaohjelmat on perinteisesti jaettu numeerisiin ja symbolisiin. Edelliset laskevat ainoastaan numeerisia laskuja, jälkimmäiset kykenevät käsittelemään myös lausekkeita. Molemmissa on yleensä mahdollisuudet graafisten esitysten tekemiseen. Nykyään ero on hämärtynyt: symboliset ohjelmat ovat yleensä erittäin tehokkaita myös numeerisessa laskennassa, alunperin numeerisiin ohjelmiin on liitetty symbolisen laskennan mahdollistavia komponentteja.

Tunnetuimmat ja laajimpaan käyttöön levinneet symboliset ohjelmat ovat Mathematica ja Maple. Kolmantena kannattanee mainita muPad. Myös ilmaisia ohjelmia on saatavissa (esimerkiksi Maxima, Yacas), mutta ominaisuuksiltaan nämä ovat vaatimattomampia ja usein hieman vanhahtavia. Numeerisista ohjelmista merkittävimmät ovat Matlab ja Mathcad. Kummassakin on nykyään myös symbolisia ominaisuuksia, jotka ovat peräisin mukaan liitetyistä Maple-ohjelman komponenteista.

Tämä on Mathematica-dokumentti (notebook = muistikirja) ja esittelee Mathematica-ohjelman perusominaisuudet.

•Yleistä

Ohjelma tallettaa muistiin kaikki syötteet ja välitulokset. Näihin voidaan missä tahansa laskennan vaiheessa viitata tulostuksen numerolla
(esimerkiksi Out[12] tai %12). Jos tulokselle on annettu nimi (mikä on suositeltavaa), siihen voidaan viitata myös tällä nimellä.

Pitkässä istunnossa saattaa aiheutua ongelmia siitä, että muistissa on vanhoja tuloksia talletettuna nimellä, jonka käyttäjä jo on unohtanut tai jonka hän kuvittelee tarkoittavan jotakin muuta. Tämän johdosta kannattaa uuteen tehtävään ryhdyttäessä muisti puhdistaa hieman kryptisellä komennolla:

In[1]:=

Remove["Global`*"]

•Numeerinen laskenta

Numeerisessa laskennassa voidaan käyttää periaatteessa mielivaltaisen monta numeroa. Käytännössä koneen muisti ja laskenta-aika asettavat rajoituksensa. Käytetty syntaksi on luonnollinen. Kertomerkki on joko välilyönti tai *; pois sitä ei voida (yleensä) jättää. Kuten seuraavat esimerkit osoittavat, pelkän välilyönnin käyttäminen ei ole kovin selkeätä ainakaan numeerisissa laskuissa.

In[2]:=

12 13

Out[2]=

156

In[3]:=

12 * 13

Out[3]=

156

Kertoma ilmaistaan tavalliseen tapaan huutomerkillä.

In[4]:=

100 !

Out[4]=

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

Luku π syötetään nimellä Pi tai se voidaan valita valikosta. Funktiolla N sille voidaan laskea haluttu määrä desimaaleja. (Desimaaleja tunnetaan nykyään hieman yli 206 miljardia. Kovin monen desimaalin laskeminen tukkii Mathematican varsin tehokkaasti.)

In[5]:=

Pi

Out[5]=

π

In[6]:=

Pi // N

Out[6]=

3.141592653589793`

In[7]:=

N[Pi, 50]

Out[7]=

3.14159265358979323846264338327950288419716939937510582097494459`50

Laskettuihin arvoihin voidaan myöhemmin viitata:

In[8]:=

Out[3]

Out[8]=

156

In[9]:=

%3

Out[9]=

156

In[10]:=

%3/%4

Out[10]=

1/598244970794513799241661787540171156991769027335779624798672845482164102520704587236804256257413578758036525133507844604174264172544000000000000000000000000

Viittaamisesta tulee helpompaa, jos tuloksille annetaan nimet (mielellään mahdollisimman kuvaavat nimet, jolloin on itsekin helpompi muistaa, mitä mikin symboli tarkoittaa):

In[11]:=

piipotneper25 = N[Pi^E, 25]

Out[11]=

22.45915771836104547342715220454373502691`25

In[12]:=

puolikaspiipotneper25 = piipotneper25/2

Out[12]=

11.22957885918052273671357610227186743203`25

In[13]:=

2 puolikaspiipotneper25 - piipotneper25

Out[13]=

0``23.3476

Jos syötteessä on desimaaliluku (jossa käytetään desimaalipistettä, ei -pilkkua), tulos lasketaan desimaalilukuna, muutoin lasketaan ns. tarkoilla arvoilla.

In[14]:=

2^(1/2)

Out[14]=

2^(1/2)

In[15]:=

2^0.5

Out[15]=

1.4142135623730951`

Myös funktioiden arvoja voidaan laskea:

In[16]:=

Sin[2]

Out[16]=

Sin[2]

In[17]:=

Sin[2] // N

Out[17]=

0.9092974268256817`

In[18]:=

Sin[2.]

Out[18]=

0.9092974268256817`

In[19]:=

Sin[Pi/4]

Out[19]=

1/2^(1/2)

Myös kompleksiluvuilla voidaan laskea:

In[20]:=

(1 + I)^2

Out[20]=

2 i

In[21]:=

Sqrt[-1]

Out[21]=

i

In[22]:=

Exp[Sin[0.5 + 0.2 I]]

Out[22]=

1.6053706382155037`  + 0.2866403774251982` i

In[23]:=

Exp[I Pi]

Out[23]=

-1

•Symbolinen laskenta

Vastaavalla tavalla voidaan käsitellä algebrallisia lausekkeita, so. lausekkeita, joissa on kirjainsymboleja:

In[24]:=

lsk = (x + y)^12

Out[24]=

(x + y)^12

Lausekkeita voidaan muokata, esimerkiksi sieventää useilla eri tavoilla. Ei ole itsestään selvää, mitä sievä kussakin tapauksessa tarkoittaa; se riippuu siitä, mitä lausekkeelle on seuraavaksi tarkoitus tehdä. Tämän johdosta sieventämiskomentoja on useita erilaisia eikä niiden hallinta aina ole helppoa. Kunkin komennon argumentti (lauske, johon operaatio kohdistuu) annetaan hakasuluissa. Tämä on yleinen tapa merkitä funktioita Mathematicassa; funktiotahan nämä komennotkin ovat. Esimerkkeinä lausekkeen kehittäminen, tekijöihin jako ja ns. osamurtokehitelmän muodostaminen; erilaisia sievennyskomentoja on kuitenkin paljon enemmän.

In[25]:=

poly = Expand[lsk]

Out[25]=

x^12 + 12 x^11 y + 66 x^10 y^2 + 220 x^9 y^3 + 495 x^8 y^4 + 792 x^7 y^5 + 924 x^6 y^6 + 792 x^5 y^7 + 495 x^4 y^8 + 220 x^3 y^9 + 66 x^2 y^10 + 12 x y^11 + y^12

In[26]:=

Factor[poly]

Out[26]=

(x + y)^12

In[27]:=

lsk = x/(-7 + 13 x - 26 x^2 + 45 x^3 - 49 x^4 + 62 x^5 - 60 x^6 + 46 x^7 - 41 x^8 + 21 x^9 - 10 x^10 + 5 x^11 + x^12)

Out[27]=

x/(-7 + 13 x - 26 x^2 + 45 x^3 - 49 x^4 + 62 x^5 - 60 x^6 + 46 x^7 - 41 x^8 + 21 x^9 - 10 x^10 + 5 x^11 + x^12)

In[28]:=

Apart[lsk]

Out[28]=

1/(192 (-1 + x)^3) - 25/(1536 (-1 + x)^2) + 875/(36864 (-1 + x)) + 7/(2752000000 (7 + x)) + (3 ... - 102 x)/(2500 (1 + x^2)^2) + (3303 - 2704 x)/(250000 (1 + x^2)) + (-13 - 5 x)/(387 (1 + x + x^2))

Yleisiä sievennyskomentoja ovat Simplify ja FullSimplify. Mitä nämä tekevät, ei kuitenkaan ole aina selvää:

In[29]:=

lsk1 = (a^3 - b^3)/(a - b)

Out[29]=

(a^3 - b^3)/(a - b)

In[30]:=

Simplify[lsk1]

Out[30]=

a^2 + a b + b^2

In[31]:=

lsk2 = (a^15 - b^15)/(a - b)

Out[31]=

(a^15 - b^15)/(a - b)

In[32]:=

Simplify[lsk2]

Out[32]=

(a^15 - b^15)/(a - b)

In[33]:=

FullSimplify[lsk2]

Out[33]=

(a^15 - b^15)/(a - b)

In[34]:=

Cancel[lsk2]

Out[34]=

a^14 + a^13 b + a^12 b^2 + a^11 b^3 + a^10 b^4 + a^9 b^5 + a^8 b^6 + a^7 b^7 + a^6 b^8 + a^5 b^9 + a^4 b^10 + a^3 b^11 + a^2 b^12 + a b^13 + b^14

Funktioiden käsittelyyn liittyy omat sievennyskomentonsa:

In[35]:=

TrigExpand[Sin[x + y]]

Out[35]=

Cos[y] Sin[x] + Cos[x] Sin[y]

Kaikki yhden argumentin sievennyskomennot voidaan kirjoittaa myös argumentin jälkeen:

In[36]:=

lsk2 // Cancel

Out[36]=

a^14 + a^13 b + a^12 b^2 + a^11 b^3 + a^10 b^4 + a^9 b^5 + a^8 b^6 + a^7 b^7 + a^6 b^8 + a^5 b^9 + a^4 b^10 + a^3 b^11 + a^2 b^12 + a b^13 + b^14

In[37]:=

Sin[x + y] // TrigExpand

Out[37]=

Cos[y] Sin[x] + Cos[x] Sin[y]

Derivointi ja integrointi tapahtuvat yksinkertaisesti.

In[38]:=

D[Exp[Sin[x]], x]

Out[38]=

e^Sin[x] Cos[x]

In[39]:=

D[u[v[x]], x]

Out[39]=

u^'[v[x]] v^'[x]

In[40]:=

D[Log[x], {x, 2}]

Out[40]=

-1/x^2

In[41]:=

Integrate[x^5 Exp[-x], x]

Out[41]=

e^(-x) (-120 - 120 x - 60 x^2 - 20 x^3 - 5 x^4 - x^5)

In[42]:=

Integrate[x^5 Exp[-x], {x, 0, 1}]

Out[42]=

120 - 326/e

Mathematica kuitenkin tuntee tavallisten alkeisfunktioiden lisäksi melkoisen määrän myös ns. erikoisfunktioita.

In[43]:=

Integrate[Exp[-t^2], {t, 0, 2}]

Out[43]=

1/2 π^(1/2) Erf[2]

Tälle saadaan myös numeerinen arvo:

In[44]:=

% // N

Out[44]=

0.8820813907624215`

Integrointi voi tapahtua myös numeerisesti:

In[45]:=

NIntegrate[Exp[-t^2], {t, 0, 2}]

Out[45]=

0.8820813907624219`

Virheellisiä tuloksia voi kuitenkin yllättäen syntyä. Jos integroidaan symbolisesti ja tuloksesta lasketaan numeerinen arvo, saatetaan saada eri tulos kuin integroimalla suoraan numeerisesti. Vielä Mathematican edellinen versio sai seuraavista syötteistä eri tulokset. Kyseessä on sinänsä ymmärrettävä ongelma, joka aiheutuu kyseisen erikoisfunktion (EllipticE) ominaisuuksista kompleksialueella. Mikään ohjelmisto tuskin on virheetön: uudessa versiossa on uudet virheet. Käyttäjän tulee siis oppia kriittisyyteen.

In[46]:=

Integrate[Sqrt[2 - Sin[x]^2], {x, 0, 2 Pi}]

Out[46]=

4 2^(1/2) EllipticE[1/2]

In[47]:=

% // N

Out[47]=

7.640395578055424`

In[48]:=

NIntegrate[(2 - Sin[x]^2)^(1/2), {x, 0, 2 π}]

Out[48]=

7.640395578046612`

Jälkimmäisessä syötteessä on käytetty pelkän näppäimistön sijasta myös Mathematican syötepaletteja.

Aina eivät sieventämiskomennot kuitenkaan ilman lisämääreitä anna sitä, mitä odottaisi. Syykin voi olla hyvä:

In[49]:=

Simplify[Sqrt[x^2]]

Out[49]=

x^2^(1/2)

In[50]:=

Simplify[Sqrt[x^2], Element[x, Reals]]

Out[50]=

Abs[x]

In[51]:=

Sqrt[2 I]

Out[51]=

1 + i

Mutta sieventää voidaan myös väkisin, ts. käyttäjän vastuulla:

In[52]:=

PowerExpand[Sqrt[x^2]]

Out[52]=

x


Converted by Mathematica  (May 8, 2003)