Symbolinen laskenta, syksy 0 Ari Lehtonen. Johdantoa Maxima on laaja symboliseen laskentaan suunniteltu ohjelma, joka on nykyisin vapaasti saatavissa ja jaettavissa (GNU GPL). Maximalla voidaan sieventää lausekkeita, jakaa polynomeja tekijöihin, ratkaista yhtälöitä, derivoida, integroida, kehittää funktioita taylorin sarjoiksi, ratkaista differentiaaliyhtälöitä. Vaikka Maximan vahvuusalueita on nimenomaan symbolinen laskenta, on siinä paljon numeeriseen laskemiseen liittyviä toimintoja (laskeminen tarkoilla arvoilla ja likiarvoilla, suurilla kokonaisluvuilla ja suurtarkkuuslikiarvoilla, jne) sekä varsin monipuoliset piirto-ominaisuudet. Maximassa on lisäksi ohjelmointikieli, jolla Maximan toimintoja voidaan laajentaa. Maxima on siis täysiverinen matemaattinen yleisohjelmisto ja siinä käytettävissä olevan matematiikan tietämyksen nojalla sitä voidaan kutsua matemaattiseksi asiantuntijajärjestelmäksi (tosin sen käyttäjänkin pitää olla matematiikan asiantuntija). Maximan käyttäjä on tavallisesti kosketuksissa (ainakin) kolmen ohjelman kanssa. Varsinainen Maxima-ohjelma jää yleensä taustalle, mutta se on näistä kolmesta tärkein, Maximan komentoja käsittelevä laskentaydin. Käyttäjä näkee lähinnä jonkin monista käyttöliittymistä, joista näillä sivuilla käsitellään vain wxmaximaa. Muihin löytyy linkkejä Maximan kotisivulta maxima.sourceforge.net; näyttökuvia eri käyttöliittymistä löytyy Maximan screenshots.html-sivulta. Kolmas tarpeellinen ohjelma on Gnuplot, joka hoitaa Maximan kuvien tekemisen. Gnuplot-ohjelmaa voi käyttää suoraankin, mutta aluksi kuvien tekeminen Maximasta käsin lienee helpointa. Esimerkkejä. Moni Maximan komento verhoaa sisäänsä melko paljon matematiikkaa ja monesti myös mutkikkaita matemaattisia algoritmeja. Vaikka komennoilla primep, next_prime ja prev_prime saadaan näennäisen helposti selville onko annettu luku alkuluku (=jaoton kokonaisluku), lukua seuraava ja edeltävä alkuluku, pitävät komennot sisällään paljon lukuteoreettista tietoutta ja mutkikkaita algoritmeja. Komennolla power_mod(a,k,n) saadaan kokonaislukujen a, k ja n potenssin a k jakojäännös luvulla n jaettaessa (eli a k modulo n), mutta käytettävä algoritmi toimii Viimeksi muutettu 0.0.0. Itse asiassa osa internetin tietoturvasta perustuu juuri alkulukujen mutkikkaaseen käyttäytymiseen. Esimerkiksi luvun alkutekijöiden määrääminen on käytännössä mahdotonta, mutta luvun selvittäminen jaolliseksi onnistuu nopeasti.
SYMBOLINEN LASKENTA, SYKSY 0 wxmaxima: käyttöliittymä syöte Maxima: laskentaydin tulos GnuPlot: piirtoapu Kuva.. Varsinaisen laskemisen hoitaa usein taustalla toimiva Maxima. Käyttäjä on kosketuksissa käyttöliittymäohjelmaan, esimerkiksi wxmaximaan, komentojen syöttämiseksi ja tulosten esittämiseksi. Maxima käyttää tarvittaessa muita taustalla toimivia apuohjelmia; esimerkiksi GnuPlotia grafiikan muodostamiseen. huomattavan nopeasti verrattuna alkeelliseen tapaan: a k = a a a (k kpl) tarvitsee k kertolaskua, mutta power_mod(a,k,n) tarvitsee enintään log k neliöön korotusta ja kertolaskua (log k on luvun k kaksikantainen logaritmi). Numeerinen esimerkki valottaa: (%i) (%o) primep(0^); false (%i) n:next_prime(0^); (%o) 00000000009 Lasketaan 4! modulo n oikein (4! = 4 4 40 ): (%i) power_mod(, 4!, n); (%o) 7047454 Luvussa 4! olevien numeroiden lukumäärä Tarkemmin: luvun x > 0 numeroiden lukumäärä on + log 0 x. Lattiafunktio r r antaa luvun r kokonaisosan eli luku r pyöristetään kokonaisluvuksi alaspäin.
SYMBOLINEN LASKENTA, SYKSY 0 (%i4) 4!*log()/log(0), numer; (%o4) 6.70588790559 0 50 Potenssiin korotuksen 4! laskemiseen tarvittava aika, jos laskettaisiin naivilla tavalla eli (4! kpl): (%i5) %/(0^(4)*55695), numer; (%o5).480897558 0 9 Luku 55695 on vuoden pituus sekunteina; 0 4 on kuvitteellinen laskentanopeus, tässä 0 4 laskutoimitusta sekunnissa. Y.o. tulos on siis laskenta-aika vuosina!. Erikoismerkkejä Komentokieltä käyttävissä ohjelmissa osalle merkeistä on varattu erityismerkitys. Alle on poimittu tärkeimmät Maximan kätttämät merkit ja niiden käyttötarkoitus: ; puolipiste päättää komennon $ dollarimerkki päättää komennon (tulosta ei näytetä) % prosenttimerkki: edellisen laskun tulos, pilkku toimii erottimena. piste: desimaalipiste; vektoreiden ja matriisien tulot : kaksoispiste: arvon tallettaminen muuttujaan = yhtäsuuruusmerkki: yhtälöt := pari kaksoispiste-yhtäsuuruusmerkki määrittelee funktion ( ) kaarisulut ilmoittavat funktion argumentit; useita komentoja samalle komentoriville; laskujärjestyksen ryhmittäminen [ ] hakasulut: listat, vektorit; indeksoidut muuttujat tai -funktiot; indeksi listan alkioon { } aaltosulut ilmaisevat joukkoja lainausmerkki estää seuraavan symbolin arvon laskemisen (vrt. differentiaaliyhtälöt) kahdennettu lainausmerkki (ei kaksoislainausmerkki) pakottaa symbolin arvon laskemisen kaksoislainausmerkki: merkkijonot /* */ /* tämä on kommentti */. Esimerkkejä voidaan piirtää seu- Esimerkki. Kuvassa?? esiintyvä funktion kuvaaja y = sin x x raavalla komennolla: (%i) plotd(sin(x)/x, [x, -*%pi, *%pi]); plotd: expression evaluates to non-numeric value somewhere in plotting range. (%o)
SYMBOLINEN LASKENTA, SYKSY 0 4 Varsinainen kuva avautuu erilliseen ikkunaan. Maxima numeroi syötteet muotoon (%i), (%i),..., ja tulokset vastaavasti (%o), (%o),... (i input, o output). Tässä tilanteessa tulos on tyhjä; kuvaa ei tulkita piirtokomennon tulokseksi. Komennon jälkeinen teksti varoittaa, että piirrettävän lausekkeen arvoa ei ole määritelty jossakin pisteessä. Ongelmakohta on x = 0, jossa lauseke saa muodon 0 0. Huomaa komennon syntaksi eli komennon muoto (sulkujen käyttö yms) ja esimerkiksi se, että sinifunktiolle muuttuja x pitää ilmaista kaarisuluilla (tämä sama pätee kaikkiin funktioihin). Matematiikan kursseilla ollaan tässä suhteessa leväperäisempiä; merkitään sin x, ja sulkuja käytetään vain jos niitä tarvitaan ilmaisemaan laskujärjestystä (sin x + = + sin x vs. sin(x + )). Esimerkki. Maximalle luku π esitetään muodossa %pi. Jos Maximalle annetut arvot ovat tarkkoja, Maxima myös laskee tarkoilla arvoilla. Sinin arvo muuttujan arvolla π/4 (=45 ) on (%i) (%o) sin(%pi/4); Tarvittaessa laskettavasta lausekeesta voidaan pyytää numeerista likiarvoa esimerkiksi näin (huomaa jälleen lisämääreen numer=true käyttötapa): (%i) sin(%pi/4), numer=true; (%o).7070678865475 Numeerinen likiarvo voidaan laskea myös funktion float avulla: (%i4) float(sin(%pi/4)); (%o4).7070678865475 Monesti komentoa float kaivataan tarkan arvon muuttamiseen likiarvoksi esimerkiksi näin (prosenttimerkki funktion float argumenttina viittaa viimeksi suoritetun komennon tulokseen): (%i5) (%o5) sin(%pi/4); (%i6) float(%); (%o6).7070678865475 Esimerkki. Polynomi (tai muunkinlainen lauseke) voidaan jakaa tekijöiksi komennolla factor: (%i7) factor(x^9-); (%o7) (x ) ( x + x + ) ( x 6 + x + ) Algebran ja lukuteorian kursseilla selvitetään tarkemmin polynomien jaollisuutta. Edellinen tulos sanoo, että k.o. polynomin rationaalikertoimiset jaottomat tekijät ovat
SYMBOLINEN LASKENTA, SYKSY 0 5 tuloksessa näkyvät tekijäpolynomit. Jos rationaalilukujen sijasta lasketaan esimerkiksi modulo, saadaan (%i8) factor(x^9-), modulus=; (%o8) (x ) 9 Esimerkki 4. Nimetään lauseke /( + cos x) nimelle y ja integroidaan eli lasketaan dx + cos x (%i9) (%o9) y:/( + cos(x)); cos (x) + (%i0) integrate(y,x); ( ) sin(x) atan (cos(x)+) (%o0) Muuttujalle annettu arvo säilyy niin kauan kunnes sitä muutetaan tai arvo poistetaan. Muuttujan arvoja on hyvä poistaa vähän väliä, ettei vahingossa yritä käyttää muuttujaa vapaana muuttujana (kuten edellä x oli integroimismuuttuja). Arvon poistaminen tapahtuu komennolla kill: (%i) kill(y); (%o) done Esimerkki 5. Lasketaan ääretön summa n=0 Summan n=0 rn olemus riippuu luvun r arvosta. Koska luvulle r ei ole annettu arvoa, Maxima pyytää käyttäjältä summan laskemiseksi tarvittavan tiedon luvun r merkkisyydestä (neg on käyttäjän antama vastaus): (%i) ev(sum(r^n, n,0,inf), simpsum=true); Is r positive, negative, or zero? neg; (%o) r Maxima ei sievennä kyseistä summaa ilman lisämäärettä simpsum=true. Jos r <, summalla on äärellinen arvo /( r), muuten summalle ei määritellä arvoa tai, kuten on tapana sanoa, sarja hajaantuu. Maxima ilmaisee asian näin (nyt käyttäjän vastaus on pos): (%i) ev(sum(r^n, n,0,inf), simpsum=true); Is r positive, negative, or zero? pos; sum: sum is divergent. an error. To debug this try: debugmode(true); r n
SYMBOLINEN LASKENTA, SYKSY 0 6 4. Maximan komennoista Monet Maximan komennoista ovat luonteeltaan funktioita: niille annetaan yksi tai useampia muuttujia, ja k.o. komento palauttaa arvon, joka voi olla luku, lauseke, vektori, matriisi,.... Esimerkiksi edellä sin(x), power_mod(a, b, n), integrate(y, x), ev(sum(r^n, n,0,inf), simpsum). Osa komennoista ei palauta varsinaista arvoa; esimerkiksi silmukan (%i) for j: thru 5 do ( print(j^) ); 4 9 6 5 (%o) done tulos on aina done. Maxima ei pidä print-komennon tulostamia lukua j tuloksina. Tämä näkyy siitä, että näitä rivejä ei ole numeroitu (eikä niihin siis voi viitata Maximan komennoin) ja tulosrivillä (\%o) on done. Komentojen ja funktioiden toimintaa voidaan ohjata ns. systeemimuuttujien avulla. Tällaisia ovat edellä olleet numer, modulus ja simpsum. Esimerkiksi sin(%pi/4), numer=true; factor(x^9-), modulus=; ev(sum(r^n, n,0,inf), simpsum=true); Systeemimuuttujalle annettu arvo vaikuttaa omalla tavallaan lausekkeiden arvojen laskentaan. Kun arvo annetaan kuten yllä komennon rinnalla, arvon vaikutus koskee vain k.o. komennon suorittamista. Jos systeemimuuttujan arvoa muutetaan omana komentonaan, sen vaikutus kohdistuu kaikkiin seuraaviin komentoihin. Se, kummasta on kyse, funktiosta vai systeemimuuttujasta, käy selville Maximan käsikirjan kyseisen komennon syntaksin kuvauksesta. Esimerkiksi komennosta power_mod Maximan käsikirja sanoo Function ja simpsum on Option variable: (%i)? power_mod; -- Function: power_mod (<a>, <n>, <m>) Uses a modular algorithm to compute a^n mod m... (%i)? simpsum; -- Option variable: simpsum Default value: false When simpsum is true, the result of a sum is simplified.
SYMBOLINEN LASKENTA, SYKSY 0 7 Tämä edellä esitetty kahtiajako, funktiot ja systeemimuuttujat, ei kuitenkaan ole kaiken kattava. Esimerkkeinä olkoot vaikkapa looginen and ja silmukkarakenteissa tarpellinen for: (%i4)? and; -- Operator: and The logical conjunction operator. (%i5)? for; -- Special operator: for Used in iterations. See do for a description of Maxima s... 4.. Funktio vs. lauseke. Matematiikan kursseilla puhutaan tavallisesti funktioista, jotka ilmaistaan antamalla funktiolle nimi sekä sen määrittely- ja maalijoukko, esimerkiksi esimerkiksi f : R R, f(x) := sin(x ). Jos funktio esiintyy vain ohimennen, funktiota ei välttämättä nimetä, vaan saatettaisiin käyttää ilmaisua funktio R R, x sin(x ). On hyvä oppia erottamaan toisistaan funktio ja sen määrittelevä lauseke. Useimmat Maximan komennoista käsittelevät nimenomaan lausekkeita, vaikka joitakin sellaisiakin on, joille pitää antaa muuttujaksi funktio eli funktion nimi. Komennon muuttuja, joka on nimetty expr, tarkoittaa lauseketta; esimerkiksi (%i)? integrate; -- Function: integrate (<expr>, <x>, <a>, <b>) Attempts to symbolically compute the integral of <expr>... Esimerkkejä komennoista, jotka kaipaavat muuttujakseen funktion, ovat apply ja map: (%i6)? map; -- Function: map (<f>, <expr_>,..., <expr_n>) Returns an expression... <f> is either the name of a function of n arguments or is a lambda... 4.. Alkeisfunktiot. (i) Polynomit ja rationaalilausekkeet; peruslaskutoimitukset + - * / ^. (ii) exp, log (=luonnollinen, kantaluku on Neperin luku e; muita ei ole). (iii) Trigonometriset: sin, cos, tan cot, sec, csc. (iv) Arkusfunktiot: asin, acos, atan, acot, asec, acsc. (v) Hyperboliset: sinh, cosh, tanh, coth, sech, csch. (vi) Areafunktiot: asinh, acosh, atanh, acoth, asech, acsch. (vii) Lukuteoreettisia funktioita: abs, ceiling, floor, round, max (lmax listoille), min (lmin listoille), signum,! (=factorial; kertoma, joka on määritelty myös ei-kokonaislukumuuttujille), binomial, genfact (yleistetty kertoma; laskeva ja nouseva potenssi); divide, gcd (=syt), lcm (=pyj), mod, power mod, inv mod, totient, ifactors, divisors, primep, next prime, prev prime.
SYMBOLINEN LASKENTA, SYKSY 0 8 5. Lausekkeiden sieventäminen 5.. Rationaalilausekkeet. Muodostetaan viidennen asteen polynomi, jolle kertoimet arvotaan satunnaisesti: (%i) p:product(x-(random(0)-5), j,0,4); (%o) x (x + ) (x + ) Rationaalilausekkeiden sieventämiseen keskeiset komennot ovat ratsimp, expand ja factor: (%i) (%o) (%i) (%o) expand(p); x 5 + 8 x 4 + x + 4 x + 9 x ratsimp(p); x 5 + 8 x 4 + x + 4 x + 9 x (%i4) factor(%); (%o4) x (x + ) (x + ) Polynomien jakoyhtälö eli polynomin q jakaminen toisella polynomilla p: q/p = osamäärä + jakojäännös/p, t.s. q = osamäärä p + jakojäännös. Muodostetaan polynomi q: (%i5) q:product(x-(random(0)-5), j,0,5); (%o5) (x 4) (x ) x (x + ) (x + 4) (%i6) (%o6) (%i7) (%o7) q/p; (x 4) (x ) x (x + ) (x + 4) (x + ) (x + ) ratsimp(%); x 5 x 4 x + 6 x + 96 x x 4 + 8 x + x + 4 x + 9 (%i8) osamaara:quotient(q, p); (%o8) x 9 (%i9) (%o9) jakojaannos:remainder(q, p); 8 x 4 + 90 x + 0 x + 8 x Vaihtoehtoisesti divide(q,p) antaa parin [osamaara, jakojaannos]: (%i0) divide(q, p); (%o0) [x 9, 8 x 4 + 90 x + 0 x + 8 x] Tarkistetaan, että q = osamäärä p + jakojäännös:
SYMBOLINEN LASKENTA, SYKSY 0 9 (%i) q - (osamaara*p+jakojaannos); (%o) (x 9) x (x + ) (x + ) 8 x 4 90 x 0 x +(x 4) (x ) x (x + ) (x + 4) 8 x (%i) expand(%); (%o) 0 Murtolausekkeen q/p osoittaja ja nimittäjä: (%i) num(q/p); (%o) (x 4) (x ) x (x + ) (x + 4) (%i4) denom(q/p); (%o4) (x + ) (x + ) Osamurtokehitelmä jakaa rationaalifunktion yksinkertaisempien rationaalifunktioiden summaksi. (Osamurtokehitelmiä tarvitaaan mm. rationaalifunktioiden integroinnin yhteydessä.) (%i5) partfrac(q/p, x); 45 (%o5) 4 (x + ) + 6 (x + ) + 67 4 (x + ) 5 (x + ) + x 9 (%i6) rat(%); x 5 x 4 x + 6 x + 96 x (%o6)/r/ x 4 + 8 x + x + 4 x + 9 (%i7) factor(%); (x 4) (x ) x (x + ) (x + 4) (%o7) (x + ) (x + ) Käytetyt muuttujat ja niiden arvot saadaan selville näin: (%i8) values; (%o8) [p, q, osamaara, jakojaannos] (%i9) ev(values); (%o9) [x (x + ) (x + ), (x 4) (x ) x (x + ) (x + 4), x 9, 8 x 4 + 90 x + 0 x + 8 x] Muuttujien arvot kannattaa yleensä poistaa vähän väliä: (%i0) kill(values); (%o0) done
SYMBOLINEN LASKENTA, SYKSY 0 0 5.. Juurilausekkeet. Neliön neliöjuuri ja kuution kuutiojuuri sievenevät automaattisesti: (%i) sqrt(a^); (%o) a (%i) (a^)^(/); (%o) a Tulon neliöjuuri ei sievene automaattisesti (tähän on syynsä): (%i) ab:sqrt(a*b); (%o) a b Komento radcan pakottaa sieventämisen: (%i4) radcan(%); (%o4) a b Mutta jos tähän tulokseen sijoitetaan a = ja b = (%i5) subst([a=-, b=-], %); (%o5)... niin saadaan eri tulos kuin sijoittamalla lausekeeseen a b : (%i6) subst([a=-, b=-], ab); (%o6) Sääntö a b = a b ei siis päde kaikille luvuilla a ja b. Monimutkaisten lausekkeiden vertaaminen onnistuu usein helpoiten tutkimalla niiden erotusta: (%i7) lauseke:(sqrt(r^ + a^) + a)*(sqrt(r^ + b^) + b)/r^; ( r + a + a ) ( r + b + b ) (%o7) r (%i8) lauseke:(sqrt(r^ + a^) + sqrt(r^ + b^) + a + b)/ (sqrt(r^ + a^) + sqrt(r^ + b^) - a - b); r + b (%o8) + r + a + b + a r + b + r + a b a (%i9) ratsimp(lauseke - lauseke); (%o9) 0 (%i0) kill(values)$
SYMBOLINEN LASKENTA, SYKSY 0 5.. Trigonometriset lausekkeet. Trigonometristen lausekkeiden sieventäminen on mutkikkaampaa kuin rationaalisten, koska trigonometrisilla funktioilla on monenlaisia identiteettejä. (%i) esim:(sin(x)^4-6*cos(x)^*sin(x)^ + 4*(cos(x)^-sin(x)^) + 8*sin(x) + cos(x)^4 + )/(8*cos(x)^); (%o) sin (x)4 6 cos (x) sin (x) + 4 ( cos (x) sin (x) ) + 8 sin (x) + cos (x) 4 + 8 cos (x) (%i) trigrat(esim); cos (4 x) + 4 cos ( x) + 8 sin (x) + (%o) cos ( x) + 6 cos (x) (%i) trigsimp(esim); sin (x) + cos (x)4 (%o) cos (x) Maxima tulkitsee hyperboliset funktiot sieventämisen suhteen trigonometrisiksi, koska nillä on paljon vastaavanlaisia indentiteettejä. (%i4) esim:sech(x)^*sinh(x)*tanh(x)/coth(x)^ + cosh(x)^*sech(x)^*tanh(x)/coth(x)^ + sech(x)^*tanh(x)/coth(x)^; (%o4) sech (x) sinh (x) tanh (x) coth (x) (%i5) trigsimp(esim); (%o5) sinh (x)5 + sinh (x) 4 + sinh (x) cosh (x) 5 + cosh (x) sech (x) tanh (x) coth (x) + sech (x) tanh (x) coth (x) Ns. kanooninen muoto hyperbolisille funktioille on kuitenkin esitys eksponenttifunktion avulla: (%i6) trigrat(esim); (%o6) e0 x + e 9 x + e 8 x 8 e 7 x 4 e 6 x + e 5 x + 4 e 4 x 8 e x e x + e x e 0 x + 5 e 8 x + 0 e 6 x + 0 e 4 x + 5 e x + Sinin arvo kompleksiselle muuttujan arvolle: (%i7) esim:sin((+*%i)^); (%o7) sin ( ( i + ) ) pelkkä trigexpand ei riitä: (%i8) trigexpand(esim); (%o8) sin ( ( i + ) )
SYMBOLINEN LASKENTA, SYKSY 0 (%i9) expand(esim); (%o9) sin ( i + 5) (%i40) trigexpand(%); (%o40) i cos (5) sinh () + sin (5) cosh () Kompleksiluvut saadaan yleensä mukavimmin normaaliin muotoonsa a + b i, missä a ja b ovat reaaliset, komennolla rectform: (%i4) rectform(esim); (%o4) i cos (5) sinh () + sin (5) cosh () (%i4) float(%); (%o4) 08.6899966 i 7804.760576558 (%i4) cabs(%); (%o4) 877.95707968 (%i44) kill(values)$ 6. Yhtälöiden ja yhtälöryhmien ratkaiseminen 6.. Polynomiyhtälöt. Polynomi on muotoa a n x n + a n x n + + a x + a 0 oleva lauseke, missä a j ovat vakioita ja n ei-negatiivinen kokonaisluku. (%i) equ:x^-*x^+4*x-; (%o) x x + 4 x (%i) wxplotd(equ, [x,-,4]); (%t) (%o)
SYMBOLINEN LASKENTA, SYKSY 0 (%i) solve(equ=0, x); i ( (%o) [x = ( ) + ( ) ( x = ) i ( ( ) x = ( ) + ] i ) ( ) i +, ) +, (%i4) float(%); (%o4) [x =.078048777 (.8660540784486 i 0.5) +.9458049989 (.8660540784486 i 0.5) +.0, x =.9458049989 (.8660540784486 i 0.5).078048777 (.8660540784486 i 0.5) +.0, x =.76796798] (%i5) rectform(%); (%o5) [x =.469094009.654999975 i, x =.654999975 i +.469094009, x =.76796798] Komennon solve sijasta voidaan käyttää komentoa algsys (katso syntaksi tarkkaan): (%i6) algsys([equ=0], [x]); (%o6) [[x =.4690940.654999975 i], [x =.654999975 i +.4690940], [x =.767866574]] (%i7) algsys([equ=0], [x]), algexact=true; ( ) (%o7) [[x = ( ) + ], ( ) ( [x = ) i i ( ) + ], i ( ) ( [x = ( ) + ) i + ]]
SYMBOLINEN LASKENTA, SYKSY 0 4 6.. Vaikka polynomiyhtälön juuret ovatkin reaaliset, saattaa ratkaisukaavoista saada sellaisen kuvan, että juuret olisivat kompleksiset (juuren lauseke näyttää sisältävän imaginaariyksikön %i). Tämä on kolmannen asteen yhtälöille ominaista tapauksessa, jossa yhtälön diskriminantti on negatiiviinen (ns. casus irreducibilis eli supistumaton tapaus). (%i8) equ:x^+*x^-; (%o8) x + x (%i9) wxplotd(equ, [x,-,]); (%t9) (%o9) (%i0) solve(equ=0, x); ( ) ( i (%o0) [x = ) ( ) ( ) 4 i + i i, x = + ( ) i i ( ), x = + i ( ) ] i (%i) juuret:rectform(%); ( ( ) 4 π (%o) [x = i sin sin ( ) π 9 9 cos ( ) ( π ( ) 9 8 π, x = i sin + sin ( ) π 9 9 cos ( ) π ( ) 9 π, x = cos ] 9 ( cos π 9 )) ( cos π 9 ( 4 π + cos 9 )) +cos ) + ( 8 π 9 ( sin π ) 9 ) ( sin π 9 (%i) float(%); (%o) [x =.65706446669, x =.0046557 0 6 i.8798545786, x = 0.50888867956] Juuret ovat oikeasti reaaliset; toisen juuren. 0 6 i johtuu pyöristysvirheistä. )
SYMBOLINEN LASKENTA, SYKSY 0 5 6.. Joskus juuria näyttää tulevan liian vähän: (%i) equ:x^-*x+; (%o) x x + (%i4) wxplotd(equ, [x,-,]); (%t4) (%o4) (%i5) solve(equ=0, x); (%o5) [x =, x = ] Tällaisessa tilanteessa kannattaa tarkistaa muuttuja multiplicities; se kertoo kunkin juuren kertaluvun: (%i6) multiplicities; (%o6) [, ] Juuri x = on yksinkertainen ja juuri x = on kaksinkertainen; tämä nädään myös tekijöihin jakamalla: (%i7) factor(equ); (%o7) (x ) (x + ) 6.4. Yhtälön likimääräinen ratkaisu. Kolmannen asteen polynomeille käytettävä ratkaisukaava on ns. Cardanon kaava. Vastaava kaava on olemassa neljännen asteen yhtälöille, mutta korkeamman asteen yhtälöille Abel ja Galois osoittivat 800-luvun alussa, että sellaisia kaavoja ei ole olemassa. (%i8) equ:x^5+*x^-; (%o8) x 5 + x (%i9) wxplotd(equ, [x,-,]);
SYMBOLINEN LASKENTA, SYKSY 0 6 (%t9) (%o9) (%i0) solve(equ=0, x); (%o0) [0 = x 5 + x ] solve ei yhtälöä pysty ratkaisemaan, mutta juurten likiarvot saadaan selville komennolla allroots: (%i) allroots(equ=0); (%o) [x =.560700077087, x =.5994079656858, x =.480469499, x =.75797574656 i+.690898047, x =.690898047.75797574656 i] 6.5. Muille kuin polynomiyhtälöille tarvitaan komentoja find_root, newton, mnewton yms. (%i) find_root(equ=0, x, -,-); (%o).480469499 (%i) find_root(equ=0, x, -,0); (%o).5994079656858 (%i4) find_root(equ=0, x, 0,); (%o4).560700077087 (%i5) load(newton)$ (%i6) newton(equ, x, -, 0^(-5)); (%o6).480469406404 (%i7) newton(equ, x, -0.5, 0^(-5)); (%o7).599407984088 (%i8) newton(equ, x,, 0^(-5)); (%o8).5607696594
SYMBOLINEN LASKENTA, SYKSY 0 7 7. Differentiointia 7.. Muuttujasta x riippuvan lausekkeen y derivaatta y = dy/dx saadaan komennolla diff(y,x): (%i) (%o) diff(x^*sin(x), x); x sin (x) + x cos (x) Derivointimuuttuja on syytä ilmaista (mikä on del(x)?): (%i) (%o) diff(x^*sin(x)) = diff(x^*sin(x)); del ( x sin (x) ) = ( x sin (x) + x cos (x) ) del (x) 7.. Raja-arvot. Muuttujasta x riippuvan lausekkeen y raja-arvo pisteessä x 0 saadaan komennolla limit(y,x,x0): (%i) (%o) y:(-x^/-cos(x))/((-exp(x))*sin(x))^; cos (x) x + ( e x ) sin (x) (%i4) limit(y, x, 0); (%o4) 4 Paremman kuvan saa tarkastelemalla lausekkeen y osoittajan ja nimittäjän Taylorin polynomeja. Funktion n.s Taylorin polynomi pisteessä x 0 on n n! f (k) (x 0 ) (x x 0 ) k. (%i5) (%o5) yo:num(y); cos (x) x + (%i6) yn:denom(y); (%o6) ( e x ) sin (x) (%i7) (%o7)/t/ (%i8) (%o8)/t/ (%i9) (%o9)/t/ taylor(yo, x,0,6); x4 4 + x6 70 +... taylor(yn, x,0,6); x 4 + x 5 + x6 4 +... taylor(y, x,0,6); 4 + x 4 4 x 440 k=0 + x 440 467 x4 60480 67 x5 47 x6 + 060 06800 +...
SYMBOLINEN LASKENTA, SYKSY 0 8 7.. Elliptinen integraali. Maximassa on valmiina paljon ns erikoisfunktioita. Katsotaan esimerkkinä Jacobin elliptistä toisen lajin integraalia. (%i0) kill(t,s,m)$ (%i) elliptic_e(t,m) = integrate( sqrt(-m*sin(s)^), s,0,t); t (%o) elliptic e (t, m) = m sin (s) ds 0 0 (%i) elliptic_ec(m) = integrate( sqrt(-m*sin(s)^), s,0,%pi/); π (%o) elliptic ec (m) = m sin (s) ds Elliptisen integraalin tarkkaa arvoa ei (poikkeustapauksia lukuunottamatta) pystytä esittämään alkeisfunktioiden avulla, mutta sillä voidaan laskea kuten millä tahansa funktiolla. Tässä derivaatta muuttujan t suhteen ja arvo pisteessä t = 0: (%i) diff(elliptic_e(t,m), t); (%o) m sin (t) (%i4) elliptic_e(0,m); (%o4) 0 Taylorin polynomin avulla integraalille saadaan likiarvo: (%i5) taylor(elliptic_e(t,m), t,0,0); (%o5)/t/ t m t 6 ( m 4 m) t 5 (45 m 60 m + 6 m) t 7 0 5040 (575 m4 50 m + 008 m 64 m) t 9 +... 6880 7.4. Usean muuttujan funktiot. Derivaatta df(x, y)/dx = osittaisderivaatta muuttujan x suhteen; normaali tapa merkitä osoittaisderivaattoja on f(x, y)/ x. (%i6) diff( f(x,y), x); d (%o6) f (x, y) d x Lausekkeen f(x, y) ns. kokonaisdifferentiaali on f(x,y) dx + f(x,y) dy; koordinaattidifferentiaalien dx ja dy kunnollinen määrittely kaipaisi tovin enemmän aikaa (tulevat x y kurssilla Vektorifunktioiden analyysi A): (%i7) diff( f(x,y) ); ( ) d (%o7) f (x, y) del (y) + d y ( ) d f (x, y) del (x) d x Lasketaan lausekkeelle x sin y osittaisderivaatat muuttujien x ja y suhteen:
SYMBOLINEN LASKENTA, SYKSY 0 9 (%i8) y:x^*sin(y); (%o8) x sin (y) (%i9) [diff(y, x), diff(y, y)]; (%o9) [ x sin (y), x cos (y)] (%i0) kill(values)$ 8. Integrointia 8.. Määräämätön integraali lausekkeelle (%i) y:x^*sin(x); (%o) x sin (x) (%i) integrate(y, x); (%o) x sin (x) + ( x ) cos (x)... ja määrätty integraali (%i) integrate(y, x,0,*%pi); (%o) 4 π 8.. Lasketaan kolminkertainen integraali (%i4) integrate( integrate( integrate( (+z^(/))/sqrt(z), z,0,y), y,0,x), x,0,); (%o4) x y 0 0 0 z + dzdydx z Yksinkertainen lainausmerkki ennen komentoa integrate estää kyseisen komennon suorittamisen, joten aluksi voidaan nähdä, mitä ollaan tekemässä. Integrointimuuttujista z ja y pitää kertoa, että ne ovat positiiviset; tätä Maxima ei osaa lukea tiedoista, että z on välillä [0, y], y on välillä [0, x] ja x on välillä [0, ]: (%i5) integrate(integrate(integrate( (+z^(/))/sqrt(z), z,0,y), y,0,x), x,0,); Is y positive, negative, or zero? pos; Is x positive, negative, or zero? pos; (%o5) 44 805 Jos tällaiset kyselyt kyllästyttävät, muuttujia koskevat olettamukset voidaan tehdä etukäteen:
SYMBOLINEN LASKENTA, SYKSY 0 0 (%i6) assume(x>0, y>0); (%o6) [x > 0, y > 0] (%i7) integrate(integrate(integrate( (+z^(/))/sqrt(z), z,0,y), y,0,x), x,0,); (%o7) 44 805 Muuttujista x ja y tehdyt oletukset on syytä unohtaa, etteivät ne aiheuta ongelmia myöhemmin: (%i8) forget(x>0, y>0); (%o8) [x > 0, y > 0] 8.. Vähän hankalampi integraali: (%i9) y:x*sin(a*x)/(x^4 + 4); x sin (a x) (%o9) x 4 + 4 (%i0) integrate(y, x); (%o0) ( (( a x 4 + 8 a ) sin (a x) + ( a x 4 + 8 a ) cos (a x) ) ( x 4 4) cos (a x) ( a x 8 + 6 a x 4 + a) sin (a x) + ( a x 8 + 6 a x 4 + a) cos (a x) dx + (( a x 4 + 8 a ) sin (a x) + ( a x 4 + 8 a ) cos (a x) ) / ( x 4 4) cos (a x) a x 8 + 6 a x 4 + a dx + x cos (a x) sin (a x) + x cos (a x) + x cos (a x)) ( ( a x 4 + 8 a ) sin (a x) + ( a x 4 + 8 a ) cos (a x) ) Tulos sisältää alkuperäistä mutkikkaamman integraalin, joten se on hyödytön. Määrätyn integraalin Maxima osaa kuitenkin laskea: (%i) integrate(y, x,minf,inf); Is a positive, negative, or zero? pos; (%o) π e a sin (a) 8.4. Numeerinen integrointi. Lasketaan seuraavan lausekkeen integraali integraalifunktion avulla, tarkka arvo määrätylle integraalille ja numeerinen likiarvo likimääräismenetelmällä: (%i) y:cos(x)/(5 + 4*cos(x))^; cos (x) (%o) (4 cos (x) + 5)
SYMBOLINEN LASKENTA, SYKSY 0 (%i) i:integrate(y, x); (%o) 5 sin (x) ( ) (cos (x) + ) 9 sin(x) + 8 (cos(x)+) (%i4) ev(i, x=*%pi); (%o4) 0 (%i5) ev(i, x=0); (%o5) 0 ( 4 atan sin(x) (cos(x)+) 7 ) Koska päätearvot ovat molemmat nollia, pitäisi olla π 0 y dx = 0. Mutta (%i6) integrate(y, x,0,*%pi); (%o6) 8 π 7 (%i7) float(%); (%o7) 0.9084677009 Missä lienee vika? (Derivoimalla voi tarkistaa, että määräämättömän integraalin lauseke on oikein, joten... ) Monimutkaisten funktioiden integraaleja ei välttämättä pystytä esittämään yksinkertaisessa muodossa. Vaihtoehtona voidaan käyttää numeerista integrointia. Esimerkiksi komento romberg(lauseke, muuttuja_x, x_alaraja, x_ylaraja) laskee integraalin käyttäen numeerisia menetelmiä: (%i8) romberg(y, x,0,*%pi); (%o8).9084579568 (%i9) kill(values)$ 8.5. Vielä eräs hankala integraali. (Tämä esimerkki kannattaa miettiä uudestaan, kun osamurtokehitelmän käyttö on tutumpaa integraalien laskemisen apuvälineenä). (%i40) poly:x^5 + x + ; (%o40) x 5 + x + (%i4) solve(poly = 0, x); i ( (%o4) [x = ( ) + 9 5 54 ( ) ( x = 5 ) i + i 54 ( 9 ) ( 5 ) i + 54, 5 54 ) +,
( ) x = 5 + 54 ( 9 i + x =, i x = ] SYMBOLINEN LASKENTA, SYKSY 0 5 54 (%i4) factor(poly); (%o4) ( x + x + ) ( x x + ) ) +, (%i4) partfrac(/poly, x); x 4 x + 5 (%o4) 7 (x x + ) x 7 (x + x + ) (%i44) integrate(/poly, x); ( ) x 4 x+5 x (%o44) dx x + log (x + x + ) 5 atan x+ + 7 4 7 Integrointi jää hieman kesken, syystä. Syy näkyy seuraavassa: %r... tarkoittaa summaa lausekkeesta, jossa muuttujan %r paikalle sijoitetaan vuoronperään kaikki yhtälön x x + = 0 ratkaisut: (%i45) integrate(/poly, x), integrate_use_rootsof:true; (%o45) (%r 4 %r+5) log(x %r) %rinrootsof(x x +) %r %r 7 Vastaava määrätty integraalikaan ei ole järin houkutteleva: (%i46) integrate(/poly, x,0,); (%o46) ( + ( 96505 49 0 5 5 + 009406977775 49 9 + + 7 + 0 4 9 + 0 5 6 log (x + x + ) 5 atan + 4 ( ) x+ 7 atan B @ 8 9 + C + 5 A + 0 + 6804855805 49 5 4899645 49 9 9 + 4 6 9 + 5 log B @ 7 6 9 + 6804855805 46 5 + 4899645 46 9 log(( 9 + 8 + 7 6 + 9 + + 4 + 5 6 + 9 4 )/( 9 + 8 + 7 6 ))) + + ( 5795078400 5 5 + 8569974800 0 0 4 9 + + 7 + atan B @ 8 9 + 0 5 6 9 + C + 5 A + C A +
SYMBOLINEN LASKENTA, SYKSY 0 0 9 + 4 6 9 + 5 + 547477660056576 5 906598899 7 log B @ 7 6 9 + 060049690504 5 + 98687808 7 log(( 9 + 8 + 7 6 + 9 + + 4 + 5 6 + 9 4 )/( 9 + 8 + 7 6 )) + 96769464664 5 057787096 9 log ()+ 0480995840 5 + 404045468676055040 π)+ 7505 50 5 5 8874960797955 50 0 0 4 9 + + 7 + atan B @ 8 9 + 0 5 6 9 + C + 5 A + 0 + 655996005 56 5 578479565 5 7 9 + 4 6 9 + 5 log B @ 7 6 9 + 0096940405 47 5 + 9509845 47 7 log(( 9 + 8 + 7 6 + 9 + + 4 + 5 6 + 9 4 )/( 9 + 8 + 7 6 )) + 476580465 47 5 460605 47 9 log (), + 460755 47 5 + 668448896955 47 π) + 88 «+ 4968 + 55 + 05 (4 + + 88 5 «+ 4904 + 55 5 + 95 «+ 447 + 55 7 + 7945 88 7 5 + + + 5 + + 75 4 C A + C A + «4 + 5 + + 5 4 «) (%i47) %, numer; (%o47).65890078557 Numeerinen likiarvo olisi ollut helpompi määrätä: (%i48) romberg(/poly, x,0,); (%o48).65889478650859 9. Summien laskemisesta (%i) load(simplify_sum)$ (%i) (%o) 9.. Lasketaan seuraava summa: sum(n^0, n,,k); k n= n 0 Maximaa pitää useimmiten kovistella enemmän summien sieventämiseksi:
SYMBOLINEN LASKENTA, SYKSY 0 4 (%i) (%o) sum(n^0, n,,k), simpsum; 6 k + k 0 + 55 k 9 66 k 7 + 66 k 5 k + 5 k 66 9.. Päättymättömän geometrisen sarjan summa: (%i4) (%o4) sum(q^n, n,0,m), simpsum; q m+ q (%i5) sum(q^n, n,0,inf), simpsum; Is q positive, negative, or zero? neg; (%o5) q 9.. Ns. Eulerin summat ovat seuraavaa muotoa, missä m on positiivinen kokonaisluku: (%i6) (%o6) (%i7) (%o7) (%i8) (%o8) es_m:sum(/n^(*m), n,,inf); n m n= simplify_sum(ev(es_m, m=)); π 6 simplify_sum(ev(es_m, m=)); π 4 90 (%i9) (%o9) simplify_sum(ev(es_m, m=)); π 6 945 Laskeeko Maxima kyseiset summat oikeasti? Ei toki. Ei äärettömän montaa termiä voi laskea yhteen äärellisessä ajassa. Maxima käyttää seuraavia kaavoja: (%i0) zerobern:true$ (%i) es_m = (-)^(m-)*(*%pi)^(*m)*bern(*m)/(*(*m)!); (%o) n = ( )m m π m bern ( m) m ( m)! n=
SYMBOLINEN LASKENTA, SYKSY 0 5 (%i) makelist( (-)^(m-)*(*%pi)^(*m)*bern(*m)/(*(*m)!), m,,0); (%o) [ π 6, π4 90, π6 945, π 8 9450, π 0 9555, 69 π 685875, π 4 845, 67 π 6 56456650, 4867 π 8 8979954805, 746 π 0 594659065 ] 9.4. Seuraavan summan laskeminen käsin vaatii hieman kekseliäisyyttä: (%i) +*sum(r^n*cos(n*x), ( n,,inf); ) (%o) r n cos (n x) + n= (%i4) simplify_sum(%); Is r positive, negative, or zero? neg; (%o4) (r cos (x) r ) r cos (x) r (%i5) ratsimp(%); r (%o5) r cos (x) r 9.5. Myös seuraavat summat vaativat miettimistä: (%i6) s:sum(-cos(n*x), n,,k); k (%o6) cos (n x) n= (%i7) s_simp:simplify_sum(s); sin (x) sin ((k + ) x) + (cos (x) ) cos ((k + ) x) + cos (x) (%o7) cos (x) (%i8) s:diff(s, x); k (%o8) n sin (n x) n= (%i9) simplify_sum(s); (%o9) (((i k + i) sin (x) + ( k ) cos (x) + k) sin ((k + ) x) + ((k + ) sin (x) + (i k + i) cos (x) i k) cos ((k + ) x) + ( i k sin (x) + k cos (x) k ) sin (k x) + (k sin (x) + i k cos (x) i k i) cos (k x))/(4 cos (x) 4) (%i0) trigrat(%); k sin ((k + ) x) + ( k ) sin (k x) (%o0) cos (x)
SYMBOLINEN LASKENTA, SYKSY 0 6 0. Lineaarialgebraa 0.. Vektorit. Vektorit ilmaistaan Maximalle listoina. Esimerkiksi 4 (%i) v:[,,-]; (%o) [,, ] (%i) v:[%gamma, %e, %pi]; (%o) [γ, e, π] (%i) v+v; (%o) [γ +, e +, π ] (%i4) float(%); (%o4) [.5775664905, 4.78888459045,.4596558979] Listat ovat Maximassa käytössä monessa muussakin paikassa. Aiemmin ne ovat näkyneet yhtälöiden ja yhtälöryhmien ratkaisujen esittämisessä. Listat ovat varsin käyttökelpoisia tavaravarastoja. Sisätulo ilmaistaan tavallisella pisteellä (ei kertomerkillä ) (%i5) (%o5) v.v; π + γ + e (%i6) float(%); (%o6).878666898 Vektoreiden ristituloa ei ole valmiina, mutta se on helppo määritellä (%i7) cross(u,v):= [ u[]*v[] - v[]*u[], -(u[]*v[] - v[]*u[]), u[]*v[] - v[]*u[] ]$ (%i8) cross(v,v); (%o8) [ π + e, π γ, e γ] 0.. Matriisit. Lineaarikuvaus on euklidisten avaruuksien R n ja R m välinen kuvaus L, jolle L(x + y) = L(x) + L(y) ja L(λ x) = λ L(x) kaikille x, y R n ja λ R. Kokoa m n oleva matriisi a,... a,n A =..... a m,... a m,n 4 Maximaan määritellyt erityiset vakiot ovat %e = Neperin luku, %pi = π, %phi = kultainen leikkaus = ( + 5)/, %gamma = Eulerin ja Mascheronin vakio = lim n ( n k= k log n).57756649059, %i = imaginaariyksikkö, inf = ja minf =.
SYMBOLINEN LASKENTA, SYKSY 0 7 määrittelee lineaarikuvauksen L A : R n R m, L A (x) := y, missä y j := n k= a j,k x k, t.s. L A (x) = Ax = matriisin A ja sakevektorin x matriisimielessä laskettu tulo. Kun lähtö- ja maalipuolella käytetään tavanomaista kantaa, missä kantavektorin e j j.s koordinaatti on yksi ja muut nollia, määrää jokainen lineaarikuvaus L: R n ja R m m n-matriisin A, jota vastaava lineaarikuvaus L A = L. Kun tyydytään käyttämään tavanomaisia kantoja, jokainen lineaarikuvaus R n R m on siis muotoa x Ax. Maximalle matriisit esitetään rivivektorien avulla esimerkiksi näin: (%i9) (%o9) m:matrix([,-,5],[4,-,],[-5,,0]); 5 4 5 0 (%i0) matrix_size(m); (%o0) [, ] (%i) m:matrix([-,-,-],[-,,-5],[0,-,-]); (%o) 5 0 Matriisitulo ilmastaan tavallisella pisteellä: (%i) m.m; 4 (%o) 7 8 5 Diagonaalimatriisien ja yksikkömatriisien muodostamiseen on omat komennot: (%i) diag_matrix(,,); (%o) 0 0 0 0 0 0 (%i4) ident(); (%o4) 0 0 0 0 0 0 Lineaarisia yhtälöryhmiä voidaan ratkoa komennolla solve kuten muitakin algebrallisia yhtälöitä. Lineaarisen yhtälöryhmän kerroinmatriisi saadaan poimituksi komennolla coefmatrix: (%i5) coefmatrix([5*z-*y+x=0, *z-y+4*x=0, y-5*x=0], [x,y,z]); (%o5) 5 4 5 0
SYMBOLINEN LASKENTA, SYKSY 0 8 Kun neliömatriisin determinantti on nollasta eroava, on matriisilla käänteismatriisi, joka saadaan komennolla invert tai kahdennetulla potenssiinkorotusmerkillä ^^ : (%i6) determinant(m); (%o6) (%i7) invert(m); (%o7) 5 0 5 8 9 (%i8) m^^(-); (%o8) 5 0 5 9 7 8 7 Transpoosi saadaan komenolle transpose: (%i9) transpose(m); (%o9) 4 5 5 0 Matriisin liittomatriisi muodostetaan poistamalla matriisista alkiota a i,j vastaavat rivi ja sarake, laskemalla saadun matriisin determinantti, muodostamalla näiden determinanttien avulla matriisi, ja lopuksi saadun matriisin transpoosi. Tämä onnistuu komennolla adjoint: (%i0) adjoint(m); (%o0) 5 0 5 8 9 7 (%i) mt:matrix([a[,],a[,],a[,]], [a[,],a[,],a[,]], [a[,],a[,],a[,]]); (%o) a, a, a, a, a, a, a, a, a, Liittomatriisin määräämisessä tarpeelliset alimatriisit saadaan komennolla minor: (%i) ( minor(mt, ),); a, a (%o), a, a, Neliömatriisin jälki on sen diagonaalialkioiden summa: (%i) mat_trace(mt); (%o) a, + a, + a, Matriisin rivi- ja sarakevektorit saadaan komennoilla row ja col:
SYMBOLINEN LASKENTA, SYKSY 0 9 (%i4) row(mt,); (%o4) ( a, a, a, ) (%i5) col(mt,); (%o5) a, a, a, Lineaarikuvauksen L: R n R m ydin on joukko {x R n L(x) = 0}. Maximassa lineaarikuvauksen ytimen määräämiseksi on komento nullspace, joka määrää k.o. ytimelle kannan. Vastaavasti Maxima määrää kuva-avaruudelle eli joukolle L(R n ) = {L(x) x R n } kannan komennolla columnspace. Kuva-avaruuden L(R n ) dimensiota kutsutaan lineaarikuvauksen asteeksi ja Maximassa se saadaan komennolla rank (=vastaavan matriisin aste). Komentojen nullspace ja columnspace tuloksessa esiintyvää komentoa span ei ole määritelty mitenkään. Kun komentojen antamia vektoreita tarvitaan myöhempiin laskuihin, ne pitää poimia komennolla part. (%i6) m; (%o6) 5 4 5 0 (%i7) rank(m); (%o7) (%i8) nullspace(m); (%o8) span () (%i9) columnspace(m); (%o9) span, 4, 5 5 0 Koska matriisi m on kääntyvä, on sen ydin {0}, jonka Maxima ilmaisee sanomalla, että k.o. aliavaruudella ei ole kantaa. Vastaavasti kuva-avaruuden virittäjiksi kelpaavat matriisin sarakevektorit, ne kun ovat lineaarisesti riippumattomat. Seuraavalla matriisilla tilanne on hieman toisenlainen: (%i0) m:matrix([,,], [,,4], [,4,5]); (%o0) 4 4 5 (%i) rank(m); (%o)
SYMBOLINEN LASKENTA, SYKSY 0 0 (%i) nullspace(m); (%o) span (%i) columnspace(m); (%o) span, 4 0.. Grammin ja Schmidtin ortogonalisointimenetelmällä annetusta lineaarisesti riippumattomasta vektorijoukosta {v,..., v k } muodostetaan ortogonaalinen vektorijoukko, joka virittää saman aliavaruuden kuin alkuperäiset vektorit. Maximan komennolle gramschmidt vektorijoukko {v,..., v k } ilmaistaan matriisina (vektorit v j matriisin rivivektoreita) tai listana vektoreita. (%i4) load(eigen)$ (%i5) m; (%o5) 5 4 5 0 (%i6) gramschmidt(m); (%o6) [[,, 5], [ 5, 5, ], [ 7, 7, 7 7 ]] (%i7) ratsimp(%); (%o7) [[,, 5], [ 5 5, 5, ], [ 74, 7 87, 9 74 ]] Komennolla orthogonal_complement(v_,..., v_n) määrätään annetun vektorijoukon ortogonaalikomplementille kanta. Seuraavassa määrätään matriisin m kuvaavaruuden ortogonaalikomplementille kanta (huomaa, miten komennolla part kuvaavaruuden virittäjävektorit poimitaan komentoon orthogonal_complement): (%i8) mcs:columnspace(m); (%o8) span, 4 (%i9) moc:orthogonal_complement(part(mcs,), part(mcs,)); (%o9) span Tarkistuslasku: löydetty vektori on kohtisuorassa kuva-avaruuden virittäjävektoreita vastaan (jälleen komennon span sisään piilotettu vektori poimitaan komennolla part):
SYMBOLINEN LASKENTA, SYKSY 0 (%i40) part(mcs,).part(moc,); (%o40) 0 (%i4) part(mcs,).part(moc,); (%o4) 0 0.4. Myöhemmillä kursseilla selvitetään ominaisarvoteoriana tunnettua lineaarialgebran osa-aluetta. Seuraavassa sen kummemmitta selityksittä komentoja tätä tarkoitusta varten: ominaisarvot ja -vektorit (eigenvalues, eigenvectors), karakteristinen polynomi (charpoly). (%i4) charpoly(m, x); (%o4) (( x) (5 x) 6) ( x) ( (5 x) ) + (8 ( x)) (%i4) expand(%); (%o4) x + 9 x + 6 x (%i44) solve(%=0, x); 05 9 05 + 9 (%o44) [x =, x =, x = 0] (%i45) float(%); (%o45) [x = 0.64758979799, x = 9.64758979798, x = 0.0] (%i46) eigenvalues(m); 05 9 05 + 9 (%o46) [[,, 0], [,, ]] Symmetrisen matriisin ominaisarvojen numeeriseen määräämiseen on eigens_by_jacobi: (%i47) mes:eigens_by_jacobi(m); [ (%o47) [.75650745765 0 6,.64758979799, 9.64758979798], 0.40848904686.87670940965.850897906586 0.864965809776 0.446785064.559504756 ] 0.40848904686.5484584790407.79064786 (%i48) part(mes,); 0.40848904686.87670940965.850897906586 (%o48) 0.864965809776 0.446785064.559504756 0.40848904686.5484584790407.79064786 (%i49) invert(part(mes,)).m.part(mes,); (%o49).89866074757 0 6.8777878078446 0 6 4.4408909850066 0 6.6889008767 0 7.64758979799.676955088 0 5.464099578 0 6 5.88670879807 0 6 9.64758979798
SYMBOLINEN LASKENTA, SYKSY 0 (%i50) ms:m+transpose(m); (%o50) 0 0 0 (%i5) eigenvalues(ms); ( ) ( i (%o5) [[ 76 i 9 ( ) ( i 76 i 9 ( 76 i 9 ) + (%i5) rectform(%); 0 (%o5) [[i ( ( 7 ( 7 i ( 7 ) ) 7 cos sin ) 7 ( 76 i + 0 π atan@ 76 7 A sinb @ C A 7 76 «π atan 7 76 «π atan 7 0 0 π atan@ 76 7 A sinb @ C A 7! 7 ) ( ) 7 i + ( 76 i 9 ) ( i ( 76 i 9 ) ], [,, ]] 9! + )+ ) 0 0 π atan@ 76 cos 7 A B @ C A 7 ( 7 7,! ) 0 0 π atan@ 76 sin 7 A B @ C A ) cos 0 0 π atan@ 76 cos 7 A B @ C A 7! 7,! 76 «π atan 7 ( 7 ) ( 7 ) sin 76 «π atan 7 0 0 π atan@ 76 7 A cosb @ C A, sin 7! 76 «π atan 7 + +
( 7 ( 7 ( i + 7 ( 7 ) ) ) ) cos sin 76 «π atan 7 76 «π atan 7 SYMBOLINEN LASKENTA, SYKSY 0 )+ 7 ( 7 ) 0 0 π atan@ 76 sin 7 A B @ C A cos ( 76 ) sin π atan 7 sin 7 ( 76 ) cos π atan 7 cos 7 + 7! 76 «π atan 7 76 «π atan 7 ( ) 7 76 «π atan 7 ( ) 7 (%i5) float(%); (%o5) [[.477665078,.044604950 0 6 i 4.575797659,.476004877.044604950 0 6 i], [.0,.0,.0]], 0 0 π atan@ 76 7 A cosb @ C A ], [,, ]] 7! (%i54) mes:eigens_by_jacobi(ms); (%o54) [ [.476004876, 4.575797658,.477665078],.755069584006.46589609798 0.6455045768.5787658898447.8045769895485.7805069544 ].456480047577.540564775.75654709445 (%i55) invert(part(mes,)).ms.part(mes,); (%o55).476004877 4.4408909850066 0 6.775557565689 0 6.0046557 0 6 4.57579766.6654569775 0 5 0.0.0046557 0 5.477665078 0.5. Erilaisia matriisihajotelmia saadaan komennoilla echelon(m), triangularize(m), lu_factor(m, field), cholesky(m), similaritytransform(m), get_lu_factors(x), invert_by_lu(m, (rng generalring)), lu_backsub(m, b).
SYMBOLINEN LASKENTA, SYKSY 0 4. Grafiikkaa: plot-komennot Maximan sisäänrakennetut piirtokomennot sopivat kevyeen työskentelyyn. Komennot tunnistaa nimistä, joiden osana on plot. Avuksi Maximan käsikirjan luku Plotting ja Wilhelm Haager: Graphics with MAXIMA, pdf-dokumentti osoitteessa http://www.austromath.at/daten/maxima/zusatz/graphics with Maxima.pdf. wxmaxima-käyttöliittymään piirtokomennoista on yleensä kaksi versiota: wx-alkuiset, jotka sijoittavat kuvan wxmaxima-dokumenttiin, ja ilman wx-etuliitettä olevat. Vain jälkimmäiset on dokumentoitu käsikirjaan... Funktion kuvaaja: y = f(x). Komennolla plotd voidaan piirtää yhden tai useamman yhden muuttujan funktion kuvaaja samaan kuvaan. (%i) wxplotd([x^, *x^, x^*(+sin(/x))], [x,-0.0,0.0])$ (%t) wxplot-komentojen ruudulle muodostaman kuvan voi tallettaa vain rasterigrafiikkana (png, jpg, bmp tai xpm). Tällainen kuva kelpaa vain ruudulla käytettäväksi, ei julkaistavaksi/tulostettavaksi. Kun kuva on tarkoitus tallettaa EPS-tiedostoksi, pitää wxplot-komentojen tilalle vaihtaa vastaava plot-komento ja mukaan lisätä tallennuspaikka: plotd([x^, *x^, x^*(+sin(/x))], [x,-0.0,0.0], [gnuplot_term, ps], [gnuplot_out_file, "/Users/lehtonen/plotd.eps"])$ Jos määre [gnuplot out file, <hakemisto>/<nimi>.eps ] jätetään antamatta, kuva talletetaan nimellä maxplot.ps oletushakemistoon (käyttäjän kotihakemistoon). Kuvan ohjaaminen erilaisiin ikkunointijärjestelmiin (toimivuus riipuu käyttöympäristöstä): (i) plotd([x^, *x^, x^*(+sin(/x))], [x,-0.0,0.0], [gnuplot_term, x])$ (ii) plotd([x^, *x^, x^*(+sin(/x))], [x,-0.0,0.0], [gnuplot_term, aqua])$ (iii) plotd([x^, *x^, x^*(+sin(/x))], [x,-0.0,0.0], [plot_format, xmaxima])$
SYMBOLINEN LASKENTA, SYKSY 0 5.. Tasa-arvokäyrä: f(x, y) = c. Kahden muuttujan funktion määräämä tasa-arvokäyrä piirretään komennolla wxcontour_plot: (%i) wxcontour_plot( x^ + y^, [x,-.5,.5], [y,-.5,.5], [gnuplot_preamble, "set size ratio -"] )$ (%t) Lisämääre [gnuplot_preamble, "set size ratio -"] asettaa kuvan x- ja y-akseleille saman mittayksikön. Ilman tätä asetusta ympyrät näyttävät ellipseiltä... Parametrisoitu käyrä: x = x(t), y = y(t). Parametrisoidulle tasokäyrälle pisteen koordinaatit x ja y ilmaistaan jonkin parametrin t funktiona. Parametri t voi kuvata esimerkiksi aikaa tai pitkin käyrää kuljettua matkaa ( kaarenpituusparametri ). Cornun spiraali määritellään ns. Fresnelin integraalien avulla: (%i) (%i4) cornu_spiral:[parametric, fresnel_c(t), fresnel_s(t), [t,-0,0]]$ circle:[parametric, cos(t), sin(t), [t,0,*%pi]]$ (%i5) wxplotd([cornu_spiral, circle], [nticks, 500], [gnuplot_preamble, "set size ratio -"])$ (%t5)
SYMBOLINEN LASKENTA, SYKSY 0 6.4. Data. Muuttujaan lst talletetaan lukupareja (k, s) (s kutakuinkin kuukauden k sademäärä Jyväskylässä): (%i6) lst:[[,55], [,5], [,0], [4,7], [5,50], [6,85], [7,7], [8,89], [9,8], [0,57], [,5], [,90]]$ Määre discrete kertoo plot-komennolle, että kyse on lukuparien havainnollistamisesta: (%i7) wxplotd([discrete, lst], [x,0.5,.5], [y,0,0], [style, impulses])$ (%t7).5. Kahden muuttujan funktion kuvaaja: z = f(x, y). d-grafiikka kannattaa usein piirtää komennon plotd avulla, ei wxplotd. Erilliseen ikkunaan piirrettyä d-oliota voi pyörittää hiiren avulla; wxplotd-komennon tuottama kuva on staattinen. (%i8) wxplotd(x^ - y^, [x, -, ], [y, -, ])$ (%t8)
SYMBOLINEN LASKENTA, SYKSY 0 7.6. Avaruuden parametrisoitu pinta: x = f(u, v), y = g(u, v), z = g(u, v). Edellisen satulapinnan esitys napakoordinaattien avulla: (%i9) z_rt:ev(x^ - y^, x=r*cos(theta), y=r*sin(theta)); (%o9) r cos (θ) r sin (θ) (%i0) wxplotd([r*cos(theta), r*sin(theta), z_rt], [r, 0, sqrt()], [theta, -%pi, %pi])$ (%t0). Draw-komennot Erikseen ladattava draw-kirjasto on monipuolinen grafiikkapaketti. Komennot tunnistaa nimistä, joiden osana on draw. Avuksi Maximan käsikirjan luku draw ja Wilhelm Haager: Graphics with MAXIMA, pdf-dokumentti osoitteessa http://www.austromath.at/daten/maxima/zusatz/graphics with Maxima.pdf. Draw-kirjaston graafisia objekteja: d: explicit, parametric, implicit, polar, points, polygon, rectangle, ellipse, triangle, quadrilateral, region, bars, vector, errors d: explicit, parametric, parametric surface, implicit, cylindrical, spherical, tube, points, triangle, quadrilateral, vector (%i) load(draw)$.. Funktion kuvaaja: y = f(x). Jokainen piirrettävä käyrä kehystetään explicit-tyyppiseksi grafiikkaolioksi: (%i) g:explicit(x^, x,-0.0,0.0); (%o) explicit ( x, x, 0.0, 0.0 ) (%i) g:explicit(*x^, x,-0.0,0.0)$ (%i4) g:explicit(x^*(+sin(/x)), x,-0.0,0.0)$ (%i5) wxdrawd(color=red, g, color=red, g, color=green, g)$
SYMBOLINEN LASKENTA, SYKSY 0 8 (%t5).. Tasa-arvokäyrä: f(x, y) = c. Tasa-arvokäyrä on implicit-tyyppinen olio: (%i6) wxdrawd( implicit(x^ + y^ =, x,-.5,.5, y,-.5,.5) )$ (%t6) Vaikka käyrän pitäisi yhtälönsä perusteella on ympyrä, ei se siltä näytä. draw-kirjastossa komento proportional_axes=xy tai user_preamble="set size ratio -" asettaa x- ja y-akseleille saman mittayksikön: (%i7) wxdrawd(proportional_axes=xy, implicit(x^ + y^ =, x,-.5,.5, y,-.5,.5) )$ (%t7)
SYMBOLINEN LASKENTA, SYKSY 0 9.. Parametrisoitu käyrä: x = x(t), y = y(t). Parametrimuodossa annettu käyrä kehystetään parametric-olioksi. Käyttäjän tehtäväksi jää eri käyrien eroteltavuuden järjestäminen (kuvassa värien valinta): (%i8) cornu_spiral:parametric( fresnel_c(t), fresnel_s(t), t,-5,5)$ (%i9) circle:parametric(cos(t), sin(t), t, 0, *%pi)$ (%i0) wxdrawd(proportional_axes=xy, nticks=00, color=red, cornu_spiral, color=blue, circle)$ (%t0).4. Data. Piirretään sama sademäärien kuukausijakauma kuin aiemmin. Pistepareina oleva data ilmaistaan points-tyyppisenä oliona. Pisteiden esitystapa valitaan lisämääreillä, tässä points_joined=impulses: (%i) lst:[[,55], [,5], [,0], [4,7], [5,50], [6,85], [7,7], [8,89], [9,8], [0,57], [,5], [,90]]$ (%i) wxdrawd(xrange=[0.5,.5], yrange=[0,0], fill_color=blue, points_joined=impulses, points(lst) )$ (%t)
SYMBOLINEN LASKENTA, SYKSY 0 40 Vaihdetaan datan esitystapa pylväsdiagrammiksi eli bars-olioksi. Pylväsdiagrammeja varten datapisteissä pitää kolmantena komponenttina olla pylvään leveys (tässä 0.8): (%i) lst:makelist([lst[j][], lst[j][], 0.8], j,,length(lst)); (%o) [[, 55, 0.8], [, 5, 0.8], [, 0, 0.8], [4, 7, 0.8], [5, 50, 0.8], [6, 85, 0.8], [7, 7, 0.8], [8, 89, 0.8], [9, 8, 0.8], [0, 57, 0.8], [, 5, 0.8], [, 90, 0.8]] Muutetaan lista pylväsdiagrammi-olioksi (tämän olisi voinut tehdä heti suoraankin): (%i4) apply(bars, lst); (%o4) bars([, 55, 0.8], [, 5, 0.8], [, 0, 0.8], [4, 7, 0.8], [5, 50, 0.8], [6, 85, 0.8], [7, 7, 0.8], [8, 89, 0.8], [9, 8, 0.8], [0, 57, 0.8], [, 5, 0.8], [, 90, 0.8]) (%i5) wxdrawd(xrange=[0.5,.5], yrange=[0,0], fill_color=blue, apply(bars, lst) )$ (%t5) Komennon wxdraw jälkeen kuva ei ole EPS-muodossa talletettavaksi kelpaava, kommennon draw jälkeen on. Komento draw file tallettaa viimeisimmän draw-komennolla piirretyn kuvan. (Toimiiko tämä PC:ssä?) (%i6) drawd(xrange=[0.5,.5], yrange=[0,0], fill_color=blue, apply(bars, lst) )$ draw_file(terminal=eps, dimensions=[500,000], file_name="/users/lehtonen/drawd"); Vaihtoehtoisesti: ohjataan kuva terminal-muuttujan avulla tiedostoon: drawd(terminal= eps_color, file_name="/users/lehtonen/drawd", dimensions=[500, 000], xrange=[0.5,.5], yrange=[0,0], fill_color=blue, apply(bars, lst) )$ HUOMIO: Tulostettavaksi tarkoitettu kuva pitää tallettaa EPS-muotoon (tai PDFmuotoon; JPEG tai PNG ei ole riittävä).
SYMBOLINEN LASKENTA, SYKSY 0 4.5. Kahden muuttujan funktion kuvaaja: z = f(x, y). Kahden muuttujan funktion kuvaaja on myös explicit-tyyppinen olio. Piirtokomento drawd/drawd määrää dimension. Pintaolio talletetaan muuttujaaan g, jotta sitä voitaisiin koristella eri tavoin. Oletuksena pinta piirretään rautalankamallina: (%i7) g:explicit( sin(x)*sin(y), x,-*%pi,*%pi, y,-*%pi,*%pi)$ (%i8) wxdrawd(g); (%t8) (%o8) Poistetaan piiloviivat: (%i9) wxdrawd(xu_grid=50, yv_grid=50, surface_hide=true, view=[60, 0], g); (%t9) (%o9) Lisätään kuvaan väritys lisämääreellä enhancedd=true ja xy-tasoon projisoituja tasa-arvokäyriä lisämääreellä contour=base: (%i0) wxdrawd(xu_grid=50, yv_grid=50, enhancedd=true, surface_hide=true, view=[60, 0], contour=base, g);
SYMBOLINEN LASKENTA, SYKSY 0 4 (%t0) (%o0) Erilliseen ikkunaan piirrettyä d-oliota voi pyörittää hiiren avulla; wxdrawd-komentojen tuottamat kuvat ovat täysin staattisia. (%i) drawd(xu_grid=50, yv_grid=50, enhancedd=true, surface_hide=true, view=[60, 0], contour=both, g); (%o) [grd (explicit)] Kun contour-tyyppi on map, kuvaa katsotaan suoraan ylhäältä; pinnasta piirretään korkeuskäyrästö: (%i) wxdrawd(xu_grid=50, yv_grid=50, contour_levels=0, contour=map, g); (%t) (%o)
SYMBOLINEN LASKENTA, SYKSY 0 4.6. Tasa-arvopinta f(x, y, z) = c. Piirretään pallopinta x + y + z = yhtälön avulla. (Tämä piirtotapa on laskennallisesti raskas eikä tulos ole useinkaan erityisen hyvä, mutta hätätapauksessa näinkin.) (%i) wxdrawd(enhancedd=true, surface_hide=true, proportional_axes=xyz, x_voxel=5, y_voxel=5, z_voxel=5, implicit( x^ + y^ + z^ =, x, -.,., y, -.,., z, -.,.) )$ (%t).7. Parametrisoitu pinta: x = f(u, v), y = g(u, v), z = g(u, v). Piirretään pallopinta maantieteellisen pallokoordinaattiparametrisoinnin avulla: (%i4) s:[cos(theta)*cos(phi), sin(theta)*cos(phi), sin(phi)]; (%o4) [cos (φ) cos (θ), cos (φ) sin (θ), sin (φ)] (%i5) wxdrawd(enhancedd=true, surface_hide=true, proportional_axes=xyz, xrange=[-.,.], yrange=[-.,.], zrange=[-.,.], parametric_surface( s[], s[], s[], theta, -%pi/,%pi, phi, -%pi/,%pi/) )$ (%t5)
SYMBOLINEN LASKENTA, SYKSY 0 44.8. Parametrisoitu käyrä: x = f(t), y = g(t), z = g(t). Konstruoidaan pallopinnalle käyrä, jota parametritasossa vastaa suora: (%i6) s_c:ev(s, phi=0.*theta); (%o6) [cos (0. θ) cos (θ), cos (0. θ) sin (θ), sin (0. θ)] (%i7) c:parametric(s_c[], s_c[], s_c[], theta, -6*%pi, 6*%pi)$ Spiraali (ns. loksodromi) pallopinnalla etelänavalta pohjoisnavalle: (%i8) wxdrawd(enhancedd=false, surface_hide=true, proportional_axes=xyz, xrange=[-.,.], yrange=[-.,.], zrange=[-.,.], nticks=500, line_width=, color=red, c)$ (%t8) Yhdistetään pallopinta ja loksodromi: (%i9) wxdrawd(enhancedd=false, surface_hide=true, proportional_axes=xyz, xrange=[-.,.], yrange=[-.,.], zrange=[-.,.], parametric_surface( s[], s[], s[], theta, -%pi,%pi, phi, -%pi/,%pi/), nticks=500, line_width=, color=red, c)$ (%t9)