Pari/GP

Kohteesta Linux-aktivaattori
Loikkaa: valikkoon, hakuun


Tämä PARI/GP:n esittely on kirjoitettu Turun yliopiston matematiikan laitoksen tarpeeseen ja seuraa osittain Parin omilta www-sivuilta löytyvää tutorialia.

PARI/GP on erityisesti lukuteorian tarpeisiin suunnattu tietokonealgebrajärjestelmä. Pari soveltuu myös moneen muuhun matemaattiseen käyttöön. Komentokäyttöliittymän lisäksi se sisältää myös C-kirjaston, jota voi käyttää omien laskentaohjelmien yhteydessä.

Ohjelman kuvaus sen omilta www-sivuilta:

PARI/GP is a widely used computer algebra system designed for fast computations in number theory (factorizations, algebraic number theory, elliptic curves...), but also contains a large number of other useful functions to compute with mathematical entities such as matrices, polynomials, power series, algebraic numbers etc., and a lot of transcendental functions. PARI is also available as a C library to allow for faster computations.

Originally developed by Henri Cohen and his co-workers (Université Bordeaux I, France), PARI is now under the GPL and maintained by Karim Belabas with the help of many volunteer contributors.

Käynnistys, lopetus ja opastus

Pari käynnistyy komennolla

gp

Tämä vaihe vaihtelee hieman riippuen käyttämästäsi ympäristöstä. Windowsissa luultavasti on asennuksen jäljiltä valmis pikakuvake, jota voit klikata.

Kun Pari käynnistyy, se tervehtii käyttäjää esittelemällä itsensä ja kertomalla versionsa esimerkiksi seuraavasti:

$ gp
Reading GPRC: /etc/gprc ...Done.

                                                GP/PARI CALCULATOR Version 2.3.4 (released)
                                         i486 running linux (ix86/GMP-4.2.2 kernel) 32-bit version
                              compiled: Nov  6 2008, gcc-4.3.3 20081030 (prerelease) (Ubuntu 4.3.2-2ubuntu1)
                                           (readline v5.2 enabled, extended help not available)

                                                  Copyright (C) 2000-2006 The PARI Group

PARI/GP is free software, covered by the GNU General Public License, and comes WITHOUT ANY WARRANTY WHATSOEVER.

Type ? for help, \q to quit.
Type ?12 for how to get moral (and possibly technical) support.

parisize = 4000000, primelimit = 500000
?

Viimeisellä rivillä näkyvä kysymysmerkki toimii kehotteena, eli sillä Pari kertoo odottavansa seuraavaa pyyntöäsi. Pari on nyt valmiina käyttöösi!

Jotta vältymme hämmennyksiltä, opetellaan heti aluksi, miten Pari lopetetaan. Lopetuksen voi tehdä useammalla tavalla. Joko kirjoittamalla quit tai \q taikka painamalla Unix-ympäristön lopetusnäppäinyhdistelmää ctrl-d.

Opastusta Parissa saa komennolla ?. Tarkemman opasteen haluamastaan aiheesta tai komennosta saa kirjoittamalla ? aihe.

? ?
Help topics: for a list of relevant subtopics, type ?n for n in
  0: user-defined identifiers (variable, alias, function)
  1: Standard monadic or dyadic OPERATORS
  2: CONVERSIONS and similar elementary functions
  3: TRANSCENDENTAL functions
  4: NUMBER THEORETICAL functions
  5: Functions related to ELLIPTIC CURVES
  6: Functions related to general NUMBER FIELDS
  7: POLYNOMIALS and power series
  8: Vectors, matrices, LINEAR ALGEBRA and sets
  9: SUMS, products, integrals and similar functions
 10: GRAPHIC functions
 11: PROGRAMMING under GP
 12: The PARI community

Also:
  ? functionname (short on-line help)
  ?\             (keyboard shortcuts)
  ?.             (member functions)

? ? factor
factor(x,{lim}): factorization of x. lim is optional and can be set whenever x is of (possibly recursive)
rational type. If lim is set return partial factorization, using primes up to lim (up to primelimit if lim=0)

Perus laskuoperaatiot

Harjoitellaan ensimmäiseksi aivan perus laskutoimitusten käyttöä. Yhteen-, vähennys- ja kertolasku toimivat, kuten odottaa saattaa.

? 2+3
%1 = 5
? 8-2
%2 = 6
? 5*3
%3 = 15

Jakolasku kuitenkin vaatii enemmän huomiota, sillä tilanteesta riippuu, miten haluamme sen toimivan. Ensimmäinen vaihtoehto on, että jaamme kokonaisluvun kokonaisluvulla ja haluamme käyttää tarkkaa arvoa. Silloin käytämme normaalia jakolaskun merkkiä / ja saamme tulokseksi murtoluvun.

? 3/7
%4 = 3/7

Toisena vaihtoehtona saatamme haluta samasta jakolaskusta desimaalilikiarvon. Desimaaliesityksen Pari antaa, jos joko nimittäjä tai osoittaja on annettuna reaalilukuna. Jakolaskun voi siis suorittaa jossain seuraavista muodoista:

? 3./7
%5 = 0.4285714285714285714285714286
? 3/7.
%6 = 0.4285714285714285714285714286
? 3./7.
%7 = 0.4285714285714285714285714286
? 3.0/7
%8 = 0.4285714285714285714285714286

jne. Pari siis käsittelee eri tavalla kokonaislukuja ja reaalilukuja ja jos niitä käsitellään samassa lausekkeessa, saadaan tulos reaalilukuna.

Muita käytettävissä olevia jakolaskuoperaatioita ovat \/ (tulos pyöristettynä) ja \ (tulos katkaisuna). Esimerkiksi:

? 3\/7
%9 = 0
? 4\/7
%10 = 1
? 4\7
%11 = 0
? 9\7
%12 = 1

Laskujen tarkkuus

Reaalilukuja käsitellessä Pari esittää tulokset haluamallasi tarkkuudella. Oletustarkkuus on 28 numeroa. Esimerkiksi pii:

? Pi
%13 = 3.141592653589793238462643383

tai e

? exp(1)
%14 = 2.718281828459045235360287471

(Huomaa Pi:n iso alkukirjain!) Tarkkuutta voi vaihtaa esimerkiksi 50 merkitsevään numeroon komennolla \p50.

? \p50
   realprecision = 57 significant digits (50 digits displayed)
? Pi
%15 = 3.1415926535897932384626433832795028841971693993751
? log(1)
%16 = 2.7182818284590452353602874713526624977572470937000

Ja nyt tarkkuus tosiaan on 50 numeroa.

Pari pystyy käsittelemään myös hyvinkin suuria lukuja. Kokeillaan esimerkiksi kertomaa:

? 1000!
%17 = 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044
208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823
627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119
181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428
646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586
593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589
320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398
281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546
984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319
101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103
968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146
674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289
988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906
117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458
066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788
386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790
084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774
011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221
765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068
884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428
531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433
278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573
630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889
086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135
358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000

Tässä kappaleessa lienee myös aiheellista mainita funktiot truncate(), floor() ja ceil(). Funktioiden nimet jo antavat arvata niiden merkitykset. Katkaisu, lattia ja katto. Erityisesti on huomattava katkaisun ja lattian ero, joka tulee esille negatiivisilla luvuilla.

? truncate(100*Pi)
%18 = 314
? floor(100*Pi)
%19 = 314
? ceil(100*Pi)
%20 = 315
? truncate(-100*Pi)
%21 = -314
? floor(-100*Pi)
%22 = -315
? ceil(-100*Pi)
%23 = -314

Komentojen editointi

Pari/GP on yleensä käännetty hyödyntäen GNU readline -kirjastoa, mikä tarkoittaa sitä, että siinä on käytettävissä Unix-ohjelmista, esimerkiksi bash:ista, tutut rivieditointiominaisuudet.

Ensimmäisenä ja ehkä tärkeimpänä ominaisuutena komentohistoria, eli aikaisemmin annettuja komentoja voi selata näppäimistön nuolinäppäimillä. Nuoli ylös hakee historiasta edellisen ja nuoli alas seuraavan annetun komennon.

Komentohistorian lisäksi käytettävissä on useita käteviä näppäinyhdistelmiä, joista seuraavassa tärkeimmät:

ctrl-a
Siirry komentorivin alkuun
ctrl-e
Siirry komentorivin loppuun
ctrl-k
Leikkaa kursorin kohdalta rivin loppuun. (Kill)
ctrl-u
Leikkaa kursorin kohdalta rivin alkuun.
ctrl-y
Liitä kursorin kohdalle. (Yank)
ctrl-w
Leikkaa kursorin kohdalta sanan alkuun.
ctrl-x-x
Siirry vuorotellen rivin alkuun ja takaisin.
ctrl-r
Haku historiassa taakse päin.
ctrl-s
Haku historiassa eteen päin.
ctrl-j
Lopeta haku.
ctrl-g
Lopeta haku ja palaa takaisin riville, josta haku aloitettiin.
TAB
Automaattinen komennon täydennys. Täydentää aloitetun komennon niin pitkälle kuin yksikäsitteisesti mahdollista. Jos kirjoitettu prefiksi on yksikäsitteinen, täydentää koko komennon.
alt-?
Luetteloi kirjoitetulla prefiksillä alkavat komennot.

Lisää readlinen näppäinyhdistelmiä osoitteista: http://www.bigsmoke.us/readline/shortcuts ja http://jan.tomka.name/work/doc/readline-commands.html

Komentoja kirjoittaessa voi olla myös hyödyllistä viitata aiempien komentojen tuloksiin. Tähän voidaan käyttää vastausten edessä olevaa prosenttimerkillä merkittyä numeroa. Edelliseen vastaukseen voi viitata pelkällä %-merkillä.

? %13
%24 = 3.1415926535897932384626433833
? 6 + %13
%25 = 9.141592653589793238462643383
? % - 5
%26 = 4.1415926535897932384626433833

Funktioita

Kokeillaan seuraavaksi joitain tuttuja funktioita, kuten sin(x), cos(x), exp(x) ja log(x).

? sin(x)
%27 = x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11 +
1/6227020800*x^13 - 1/1307674368000*x^15 + O(x^17)
? cos(x)
%28 = 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 - 1/3628800*x^10 + 1/479001600*x^12 -
1/87178291200*x^14 + 1/20922789888000*x^16 + O(x^18)
? exp(x)
%29 = 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + 1/5040*x^7 + 1/40320*x^8 +
1/362880*x^9 + 1/3628800*x^10 + 1/39916800*x^11 + 1/479001600*x^12 + 1/6227020800*x^13 +
1/87178291200*x^14 + 1/1307674368000*x^15 + 1/20922789888000*x^16 + O(x^17)
? log(x)
  *** log: log is not meromorphic at 0.

Kappas. Saimme Taylorin sarjoja ja yhden virheilmoituksen. Tämän tyyppisille funktioille Pari käyttää Taylorin sarjoja pisteen 0 ympäristössä. Logaritmille tämä ei kuitenkaan onnistu. Vastaava sarja löytyy kuitenkin esimerkiksi funktiolle log(x-2).

? log(x-2)
%30 = (0.69314718055994530941723212145817656807550013436026 +
3.1415926535897932384626433832795028841971693993751*I) - 1/2*x - 1/8*x^2 - 1/24*x^3 -
1/64*x^4 - 1/160*x^5 - 1/384*x^6 - 1/896*x^7 - 1/2048*x^8 - 1/4608*x^9 - 1/10240*x^10 -
1/22528*x^11 - 1/49152*x^12 - 1/106496*x^13 -1/229376*x^14 - 1/491520*x^15 + O(x^16)

Sarjojen tarkkuutta voidaan säädellä komennolla \ps n, jossa n on merkitsevien termien määrä.

? \ps 7
   seriesprecision = 7 significant terms
? sin(x)
%31 = x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + O(x^8)

Vektorit ja matriisit

Vektorit ja matriisit ovat oleellisia käsitteitä matematiikassa ja niiden käsittely on Parissakin hyvin suoraviivaista.

Vektorin syntaksi on Parissa varsin luonnollinen:

? v = [3, 12, 54, 128, 6]
%32 = [3, 12, 54, 128, 6]

Vektorin transpoosi merkitään symbolilla ~

? v~
%33 = [3, 12, 54, 128, 6]~

Vektorin pituuden saa funktiolla length() tai käyttämällä lyhennysmerkintää #v. Vektorin n:nteen elementtiin viittaaminen tapahtuu kirjoittamalla v[n].

?  length(v)
%34 = 5

? #v
%35 = 5

? v[3]
%36 = 54

Huomioitavaa on, että monesta ohjelmointikielestä poiketen vektorin indeksointi alkaa luvusta 1, ei nollasta.

Matriisin muodostaminen tapahtuu hyvin samaan tapaan ja vektori onkin helppoa ajatella matriisina, jossa on vain yksi vaakarivi. Yksittäisen alkion poimiminen matriisista onnistuu varsin luonnollisella syntaksilla. Samoin vaaka ja pystyrivien valinta.

? m = [1,2,3;4,5,6;7,8,9]
%37 =
[1 2 3]

[4 5 6]

[7 8 9]

? m[2,3]
%38 = 6

? m[2,]
%39 = [4, 5, 6]

? m[,3]
%40 = [3, 6, 9]~

Matriisien ja vektorien kertomisessa ei ole mitään ihmeellistä, kunhan niiden koot ovat laskusääntöjen mukaiset.

? m*[1,2,3]~
%41 = [14, 32, 50]~

? m * m~
%42 =
[14 32 50]

[32 77 122]

[50 122 194]

Matriisin alkioiden muuttaminen tapahtuu yksinkertaisesti sijoittamalla.

? m
%43 =
[1 2 3]

[4 5 6]

[7 8 9]

? m[2,3]=12; m
%44 =
[1 2 3]

[4 5 12]

[7 8 9]

Kuten viimeisestä komennosta huomataan, puolipiste estää sen edellä olevan komennon vastausta tulostumasta ja samalla mahdollistaa useamman komennon kirjoittamisen samalle riville. Koska rivin lopussa ei ollut puolipistettä, vain viimeisen komennon vastaus tulostui.

Muutama itsensä selittävä esimerkki lisää:

? matdet(m)
%45 = 36

? trace(m)
%46 = 15

? matsize(m)
%47 = [3, 3]

? matadjoint(m)
%48 =
[-51 6 9]

[48 -12 0]

[-3 6 -3]

? matrank(m)
%49 = 3

? matdiagonal([1,2,3,4])
%50 =
[1 0 0 0]

[0 2 0 0]

[0 0 3 0]

[0 0 0 4]

? m^(-1)
%51 = 
[-17/12 1/6 1/4]

[4/3 -1/3 0]

[-1/12 1/6 -1/12]

Käytettävä syntaksi on melko luonnollista ja funktioiden nimet melko helposti arvattavissa, varsinkin tabulaattoritäydennystä ja alt-? -vihjeitä avuksi käyttäen.

Vektoreita ja matriiseja voi muodostaa myös indekseistä riippuvilla säännöillä:

? vector(5,i,i^2)
%52 = [1, 4, 9, 16, 25]

? matrix(6,5,i,j,i+2*j)
%53 =
[3 5 7 9 11]

[4 6 8 10 12]

[5 7 9 11 13]

[6 8 10 12 14]

[7 9 11 13 15]

[8 10 12 14 16]

Jaollisuuksia

Modulolaskentaa varten Parissa on oma tyyppinsä jäännösluokille. Luvun k jäännösluokka modulo m ilmaistaan parissa muodossa: Mod(k,m).

? a=Mod(2,5); b=Mod(4,5);
? a+b
%54 = Mod(1, 5)
? a*b
%55 = Mod(3, 5)

Multiplikatiivista jäännösluokkaryhmää Z_n^* voi tutkia funktiolla znstar(n).

? znstar(15)
%56 = [8, [4, 2], [Mod(8, 15), Mod(11, 15)]]

Funktio palauttaa vektorin, joka on tulkittavissa seuraavasti. Vektorin ensimmäinen alkio kertoo ryhmän koon. Tässä tapauksessa siis kahdeksan alkiota. Toisena alkiona on vektori, joka kertoo syklisten aliryhmien koot, eli ryhmän generaattorien kertaluvut, jotka tässä tapauksessa ovat 4 ja 2. Kolmas alkio luettelee ryhmän generaattorit vastaavassa järjestyksessä.

Suurin yhteinen tekijä ja pienin yhteinen jaettava löytyvät luonnollisesti gcd()- ja lcm()-funktioilla.

? gcd(12345, 83310)
%57 = 15
? lcm(125,235)
%58 = 5875

Eräs Bezout'n hajotelma xu+yv=gdc(x,y) suurimmalle yhteiselle tekijälle löytyy luvuille x=12345 ja y=83310 seuraavasti:

? bezout(12345, 83310)
%59 = [2227, -330, 15]

Kiinalaisen jäännöslauseen ratkaisemiseen taas löytyy oma funktionsa, joka saa syötteenään tehtävän mukaiset jäännösluokat.

? chinese(Mod(3,5), Mod(2,9))
%60 = Mod(38, 45)

Kuntia

Rationaalilukujen kunnan Q laajennoksia voidaan esittää seuraavasti. Pari käsittelee kuntia olioina, joille voi tehdä monenlaisia operaatioita. Alustetaan ensin esimerkkinä kunta Q(i), eli laajennuskunta, joka saadaan lisäämällä imaginaariyksikkö i kuntaan Q.

? kunta=bnfinit(x^2+1);

Tutkitaan alkuluvun 2 haarautumista tässä kunnassa.

? idealprimedec(kunta,2)
%61 = [[2, [1, 1]~, 2, 1, [1, 1]~]]

Tuloksena on vektori, jossa on alkiona yksi vektori, joka esittää saatua alkuihannetta. Tämän vektorin ensimmäisenä alkiona on tutkittu alkuluku 2, kolmantena haaroittumisindeksi ja neljäntenä jäännösluokkaindeksi.

Jos tutkimme alkuluvun 5 haaroittumista, löydämme kaksi alkuihannetta.

? P=idealprimedec(kunta,5)
%62 = [[5, [-2, 1]~, 1, 1, [2, 1]~], [5, [2, 1]~, 1, 1, [-2, 1]~]]

Koska kunta on olio, siltä voi tiedustella sen luokkalukua "pistenotaatiolla".

? kunta.no
%63 = 1

Samoin saamme kunnan diskriminantin,

? kunta.disc
%64 = -4

sekä signatuurin.

? kunta.sign
%65 = [0, 1]

Vektorin ensimmäinen luku kertoo reaalisten upotusten määrän ja toinen kompleksisten upotusparien määrän.

Kunnan kokonaiskanta saadaan myös kuntaolion ominaisuutena.

? kunta.zk
%66 = [1, x]

Kuntien kompositioiden, eli esimerkiksi kunnan Q(i, sqrt(3)) muodostaminen voi normaalisti olla hankala tehtävä. Parilla tämä kuitenkin onnistuu seuraavasti.

Lasketaan ensin kuntien Q(i) ja Q(sqrt(3)) minimaalipolynomien avulla halutun kunnan minimaalipolynomi:

? polcompositum(x^2+1, x^2-3)
%67 = [x^4 - 4*x^2 + 16]

Ja muodostetaan tämän avulla etsitty kunta:

? kunta2 = bnfinit(x^4 - 4*x^2 + 16);


Kuvaajien plottaus

Pari on myös käytännöllinen väline kuvaajien piirtämiseen. Se tukee piirtämistä näytölle ikkunaan sekä tiedostoon useaan eri tiedostomuotoon, kuten ps, png ja gnuplot. Piirtokomennot käyttävät useita "lippuja" (flags), joilla tulostuksen toimintaa voi vaihdella. Näiden opettelu voi aluksi olla hankalaa, mutta lopputulos on yleensä kiitettävä. Nämä liput ovat yleensä 2:n potensseina olevia lukuja, jotta niitä voidaan yhdistää yksikäsitteisesti laskemalla yhteen. Määritellään näille luvuille selvyyden vuoksi muuttujanimet.

Yleisiä lippuja:

? parametric = 1;        no_x_axis = 8;       no_lines   = 64;
? recursive  = 2;        no_y_axis = 16;      points_too = 128;
? norescale  = 4;        no_frame  = 32;      splines    = 256;

(;-merkki estää Paria tulostamasta vastausriviä. Komentoja voi myös kirjoittaa useamman samalle riville.)

Objektien suhteelliseen sijoitteluun liittyviä lippuja:

? nw    = 0;     se   = 4;    relative  = 1;
? sw    = 2;     ne   = 8;

Tekstin sijoitteluun littyviä lippuja:

? bottom   = 0;    left   = 0;    hgap  = 16;
? vcenter  = 4;    center = 1;    vgap  = 32;
? top      = 8;    right  = 2;

Kuvaajan tulostuksessa riittää usein huomattavasti pienempi laskentatarkkuus kuin oletuksena oleva 28 merkitsevää numeroa. Vähennetään siis tarkkuutta:

? \p 9
   realprecision = 9 significant digits

Tulostus näytölle

Kokeillaan plottausta:

? ploth(X = -2, 2, sin(X^7))
%68 = [-2.00000000, 2.00000000, -0.999990205, 0.999990200]

Pari piirtääkin nopeasti kuvan erilliseen ikkunaan. Se piirtää komennon mukaisesti funktion sin(X^7), jossa muuttuja X kulkee arvosta -2 arvoon 2. Kuva ei kuitenkaan ole paras mahdollinen, sillä kuvan vasemmassa ja oikeassa reunassa käyrä ei käy kääntymässä funktion minimi- ja maksimiarvoissa, -1:ssä ja 1:ssä, kuten pitäisi. Syynä tähän on se, että Pari laskee funktiolle arvoja tasaisin välimatkoin annetulla välillä ja kuvion reunoilla funktio pomppii niin tiheästi, että lasketut pisteet eivät eivät anna oikeaa kuvaa funktion käyttäytymisestä. Arvoja pitäisi siis laskea tiheämmin, ainakin kuvion reunoilla.

Sinx7-1.png

Kokeillaanpa saman kuvion piirtämistä hieman toisin. Lisätään komentoon lippu 2, eli se, jolle annoimme nimen recursive.

? ploth(X = -2,2, sin(X^7), recursive)
%69 = [-2.00000000, 2.00000000, -0.999999447, 0.999999447]

Sinx7-recursive.png

Nyt kuvaaja näyttää jo selvästi paremmalta. Recursive-asetus laskee tarvittaessa pisteitä tiheämmin ja tiheämmin. Sekään ei aina kuitenkaan ole täydellinen:

? ploth(X = -2,2, sin(X*7), recursive)
%70 = [-2.00000000, 2.00000000, -0.999990206, 0.999990206]

Sinxtimes7-recursive.png

Plottaustarkkuutta voi lisätä myös kertomalla jakovälien määrä eksplisiittisesti:

? ploth(X = -2, 2, sin(X^7), , 10000)
%71 = [-2.00000000, 2.00000000, -0.999999978, 0.999999993]

Sinx7-1000.png

Tässä väli on jaettu 10000 osaan. Tällä tarkkuudella myös reunat tulostuvat oiken, vaikka keskiosalle tämä tarkkuus onkin tarpeettoman suuri.

Edellä käytetyt plottauskäskyt olivat niin kutsuttuja korkean tason plottausfunktioita. Matalan tason plottausfunktiot puolestaan tulostavat kaaviot niin kutsuttuihin ikkunoihin, joita voidaan tämän jälkeen koota samaan näytettävään kuvaan. Seuraavassa esimerkissä alustetaan ensin plotinit()-funktiolla neljä ikkunaa, joihin plotataan plotrecth()-funktiolla neljä erillistä funktiota. Tämän jälkeen ikkunat asetellaan samaan kuvaan ja näytetään.

Alustukset:

? plotinit(0,0.5,0.5,1)
? plotinit(1,0.5,0.5,1)
? plotinit(2,0.5,0.5,1)
? plotinit(3,0.5,0.5,1)

plotinit(w,x,y,flag)-funktio alustaa ikkunan w ja määrää sen kooksi vaakasuunnassa x ja pystysuunnassa y. Koska funktion viimeisenä parametrina on 1, tulkitaan x ja y osiksi koko kuvan koosta. Jos viimeinen parametri puuttuisi tai se olisi 0, pitäisi kokojen x ja y olla annettuna absoluuttisena kokona, pikseleinä.

Kuvien tulostus ikkunoihin:

? plotrecth(0,x=-Pi,Pi,sin(x))
%72 = [-3.14159265, 3.14159265, -0.999998763, 0.999998763]
? plotrecth(1,x=-Pi,Pi,cos(x))
%73 = [-3.14159265, 3.14159265, -1.00000000, 0.999995055]
? plotrecth(2,x=-Pi,Pi,sin(x)+cos(0.3*x))
%74 = [-3.14159265, 3.14159265, -0.119089892, 1.89959875]
? plotrecth(3,x=-Pi,Pi,cos(0.3*x))
%75 = [-3.14159265, 3.14159265, 0.587785252, 0.999999554]

plotrecth(w,X=a,b,expr)-funktio toimii, kuten ploth()-funktio edellä, mutta tulostus tapahtuu näytön sijasta ikkunaan numero w.

Lopullinen tulostus:

? plotdraw([0,0,0,1,0.5,0,2,0,0.5,3,0.5,0.5],1)

Plotdraw-4kuvaa.png

Tämä komento tulostaa pyydetyt ikkunat annettuihin paikkoihin listan [w1,x1,y1,w2,x2,y2,...] mukaisesti. Viimeisenä annettu lippu 1 kertoo jälleen, että sijainniksi annetut x- ja y-koordinaatit ovat suhdelukuja koko kuvan suhteen. Huomattavaa on myös, että tässä kuvassa origo on vasemmassa yläkulmassa, x kasvaa oikealle ja y alas päin.

Tulostus ps-tiedostoon

Tulostus ps-tiedostoon tapahtuu vastaavalla tavalla kuin näytölle. Tulostusfunktion nimi vain vaihtuu 'ps'-alkuiseksi.

? psploth(x = -Pi, Pi, sin(x))
%76 = [-3.14159265, 3.14159265, -0.999998763, 0.999998763]

Vastaavasti tapahtuu useamman kaavion tulostaminen samaan kuvaan. Ikkunoiden alustus ja matalan tason tulostus tapahtuvat samoilla komennoilla, mutta itse kuvat kokoavaan tulostukseen käytetään psdraw()-funktiota.

? plotinit(0,0.5,0.5,1)
? plotinit(1,0.5,0.5,1)
? plotinit(2,0.5,0.5,1)
? plotinit(3,0.5,0.5,1)
? plotrecth(0,x=-Pi,Pi,sin(x))
%77 = [-3.14159265, 3.14159265, -0.999998763, 0.999998763]
? plotrecth(1,x=-Pi,Pi,cos(x))
%78 = [-3.14159265, 3.14159265, -1.00000000, 0.999995055]
? plotrecth(2,x=-Pi,Pi,sin(x)+cos(0.3*x))
%79 = [-3.14159265, 3.14159265, -0.119089892, 1.89959875]
? plotrecth(3,x=-Pi,Pi,cos(0.3*x))
%80 = [-3.14159265, 3.14159265, 0.587785252, 0.999999554]
? psdraw([0,0,0,1,0.5,0,2,0,0.5,3,0.5,0.5],1)

Tulostus menee oletuksena tiedostoon nimeltä pari.ps. Tulostustiedoston nimeä voi muuttaa default()-funktiolla seuraavasti:

? default(psfile, "tuloste.ps")
%81 = "tuloste.ps"

Tämän jälkeen ps-tuloste ohjautuu tiedostoon nimeltä tuloste.ps.

Ohjelmointi

Pariin voi ohjelmoida myös omia funktioita ja suoritettavat komennot voi kirjoittaa suoritettavaan tekstitiedostoon. Komentojonotiedostojen käyttö mahdollistaa pitkien laskusarjojen valmistelemisen etukäteen niin, ettei itse suoritusta tarvitse jäädä valvomaan. Käydään perus kontrollirakenteet läpi lyhyillä esimerkeillä.

If-rakenne

Jotta voimme ohjelmassa suorittaa haarautumisia, tarvitsemme if-rakenteen.

? a=5
%82 = 5
? if (a==5, print("Jees!"); a=a+1, print("Ei!"))
Jees!
%83 = 6
? if (a==5, print("Jees!"); a=a+1, print("Ei!"))
Ei!
%84 = 6

Tässä siis 'if sanan jälkeen sulkuihin tulee pilkuilla erotettuina ensin ehto, toisena puolipisteellä eroteltu lista komennoista, jotka suoritetaan, jos ehto oli tosi (then-haara) ja kolmanneksi puolipisteellä eroteltu lista komennoista, jotka suoritetaan, jos ehto ei ollut tosi (else-haara). Then- tai else-haaran voi halutessaan jättää tyhjäksi. Jos ei käytä else-haaraa, voi myös jälkimmäisen pilkun jättää pois.

For-silmukka

For-silmukan rakennetta voidaan tarkastella seuraavasta esimerkistä:

? j=0
%85 = 0
? for (i=1, 10, j=j+i; print(j))
1
3
6
10
15
21
28
36
45
55

Tässä siis for-silmukka aloitetaan alustamalla silmukkamuuttuja i arvolla 1. Sen jälkeen kerrotaan, mihin arvoon asti tämä muuttuja käy. Tässä tapauksessa i saa siis arvot yhdestä kymmeneen. viimeisenä kerrotaan suoritettava komennot puolipisteellä eroteltuina. Tässä silmukassa kullakin kierroksella silmukkamuuttujan arvo lisätään ennalta nollaksi alustettuun muuttujaan, minkä jälkeen muuttujan arvo tulostetaan.

While-silmukka

Toinen tuttu silmukkatyyppi on while-silmukka.

? while (a < 9, print(a); a++)
6
7
8
? a
%86 = 9

While-silmukalle annetaan suluissa pilkulla eroteltuina ehto ja suoritettavien komentojen lista. Tässä tapauksessa silmukkaa suoritetaan, niin kauan kuin muuttujan a arvo on pienempi kuin 9. Jokaisella kierroksella tulostetaan muuttujan arvo ja kasvatetaan sitä yhdellä. (Ohjelmoijat huom! Vaikka a++ näyttää jälki-incrementoinnilta, on kyseessä esi-incrementointi.) Lopuksi tarkistettiin muuttujan arvo silmukan jälkeen.

Funktion määritteleminen

Yhdistetään edellisiä ja opetellaan samalla tekemään funktioita.

? fibo(n) = { local(a=1,b=0,temp,result=[]);
if (n>0,
  for (i=1, n,
    result=concat(result,[a]);
    temp = a;
    a = a+b;
    b = temp;);
  result,
  print("Virhe! Liian pieni n."))
}
? fibo(9)
%87 = [1, 1, 2, 3, 5, 8, 13, 21, 34]

Funktion määrittely aloitetaan antamalla yhtäsuuruusmerkin vasemmalla puolella funktion nimi ja käytettävät parametrit sulkeissa. Tämän jälkeen yhtäsuuruusmerkin oikealle puolelle kirjoitetaan ohjelman runko sulkumerkkien väliin. (Suluiksi kelpaavat sekä aaltosulut että kaarisulut.) Jos funktiossa halutaan käyttää lokaaleja muuttujia, on ne esiteltävä ja tarvittaessa alustettava heti ensimmäisenä local()-funktiolla. Yllä olevassa esimerkissä tarkistetaan ensimmäiseksi, että syötteenä saatu luku on positiivinen ja tämän jälkeen for-silmukassa lasketaan n kappaletta Fibonaccin lukuja. Laskettu luku sijoitetaan aina result-vektorin loppuun. Lopuksi funktio antaa tuloksena tämän vektorin. Jos syötteenä saatu luku ei ole positiivinen, tulostetaan virheilmoitus.

Huomattavaa on, että kukin komento(rivi) lopetetaan puolipisteeseen, jolloin kyseisen komennon mahdollisesti tuottama tulos ei tulostu. Print-komennon lisäksi ainoa komento, jolta on jätetty puolipiste pois, on tuloksen tuottava rivi:

  result,

Näin siksi, että Parissa funktio palauttaa tuloksenaan viimeisen tuloksen tuottaneen rivin tuloksen.

Komentojonotiedostot

Parille syötettävät komennot ja funktiot voi joskus olla järkevää kirjoittaa erilliseen tekstitiedostoon, komentojonotiedostoon. Tarve tälle tulee esimerkiksi siitä, että tarvitaan jotain itse tehtyä funktiota usein. Vähän pidemmän funktion kirjoittaminen jo yhdenkin kerran suoraan komentoriville on riittävän hankalaa ja niiden kirjoittaminen hoituu paljon helpommin editorilla suoraan tekstitiedostoon. Toinen tilanne, jossa komentojonotiedostot ovat käytännöllisiä, ovat tilanteet, joissa täytyy suorittaa peräkkäin useita pitkäkestoisia komentoja. Kun komennot kirjoittaa suoritettavaan tiedostoon, ei tarvitse itse jäädä odottelemaan yksittäisten komentojen valmistumista.

Kirjoitetaan esimerkiksi yksinkertainen tiedosto paritesti.gp

s = 3
t = 6
r = s + t

Tämän ohjelman voi nyt suorittaa Parista käsin komennolla:

? read("paritesti.gp")
% 88 = 9

Täytyy huomata, että Pari etsii tiedostoa työhakemistosta ja jossain tapauksessa voi joutua antamaan sille tiedoston koko polun.

Tiedoston voi lukea Pariin myös komennolla \r {tiedostonnimi}. Tämä toimii hieman eri tavalla kuin read()-funktio, kuten seuraavasta voi nähdä.

? \r {paritesti.gp}
%89 = 3
%90 = 6
%91 = 9

Tässä tiedoston jokainen komento suoritetaan yksi kerrallaan ja kunkin komennon tulos näytetään, kun edellisessä näytettiin vain viimeisen komennon tulos. Tilanteesta riippuu, kumpi toiminto on toivotumpi.

Viimeisimmän suoritetun komennon tuloksen voi kirjoittaa tiedostoon komennolla:

? \w {tiedosto.txt}

Tämä komento lisää viimeisimmän tuloksen annetun tiedoston loppuun muuttamatta tiedoston muuta sisältöä. Näin istunnosta voi poimia tärkeimmät tulokset muistiin.

Pariin viittaaminen papereissa

Jos olet käyttänyt PARI/GP:tä työssäsi ja haluat viitata siihen, voit käyttää seuraavaa BibTex-tietuetta:

@preamble("\usepackage{url}")
@manual{PARI2,
  organization = "{The PARI~Group}",
  title        = "{PARI/GP, version {\tt 2.3.4}}",
  year         = 2008,
  address      = "Bordeaux",
  note         = "available from \url{http://pari.math.u-bordeaux.fr/}"
}

Jos et käytä BibTexiä, vastaava bibliography-tietue näyttää tältä:

\bibitem{PARI2}
   PARI/GP, version {\tt 2.3.4}, Bordeaux, 2008, \url{http://pari.math.u-bordeaux.fr/}.

Vaihda vain käyttämäsi version tiedot tilalle.