Muuttujatyypin äärittely:
type kaupunki real :: pituus, leveys character (len=20) :: nimi end typeTyyppiä kaupunki olevien muuttujien määrittely:
type (kaupunki) :: turku, k1, k2 type (kaupunki), dimension(1000) :: luetteloKomponentteihin voi viitata operaattorilla %:
real :: x turku%pituus = 22.3 turku%leveys = 60.45 turku%nimi = 'Turku' x = luettelo(i)%pituusOmia tyyppejä voi käyttää sijoituslauseissa:
k1 = k2 k2 = luettelo(327)Sijoituslauseessa voidaan luetella kaikki komponentit:
k1 = kaupunki(25.0, 60.0, 'Helsinki')Myös muita operaattoreita voi määritellä (käsitellään myöhemmin).
module m ! tyyppien ja muuttujien maarittelyt ... contains subroutine sub ! aliohjelma end ... end moduleMyös moduulin proseduureilla voi olla omia sisäisiä proseduureja.
Moduulin muuttujamäärittelyt ja aliohjelmat saadaan käyttöön use-lauseella.
Moduuli käännetään erikseen ja linkitetään sitä käyttävään ohjelmaan.
Esimerkki: vakioiden määrittely
module realnum implicit none integer, parameter :: single=selected_real_kind(5) integer, parameter :: double=selected_real_kind(10) end moduleKäyttö:
program realtest use realnum implicit none real (kind=single) :: x real (kind=double) :: y ... end program
Moduulin tunnuksiin voidaan viitata myös eri nimillä:
program realtest use realnum, myreal=>double implicit none real (kind=myreal) :: x ... end programOletusarvo on, että käyttöön saadaan kaikki moduulin määrittelyt. Käyttöön voidaan ottaa myös vain halutut määrittelyt:
program realtest use realnum, only: double ... end programtai
program realtest use realnum, only: myreal=>double ... end program- Nähdään, mitä määrittelyjä on käytössä.
Moduulia käyttävä ohjelma voisi olla esimerkiksi:
program koe use ratpack implicit none type (rational) :: p, q, r p=rat(1,2) q=rat(2,3) r=p+q q=q+1 write(*,*) nomin(r),denom(r) write(*,*) nomin(q),denom(q) p=5 p= .inv. p write(*,*) nomin(p),denom(p) end programOhjelman tulostus:
7 6 5 3 1 5Yksinkertainen versio:
module ratpack type rational integer :: nominator, denominator end type contains function mul (p, q) ! lasketaan rationaalilukujen p ja q tulo type (rational) mul type (rational), intent(in):: p, q integer a,b,c,d type (rational) r a=p%nominator; b=p%denominator c=q%nominator; d=q%denominator r%nominator = a*c r%denominator = b*d mul = simplify (r) end function function div (p, q) ! lasketaan rationaalilukujen p ja q osamaara .. end function function add (p, q) ! lasketaan rationaalilukujen p ja q summa .. end function function sub (p, q) ! lasketaan rationaalilukujen p ja q erotus .. end function
function simplify (q) ! supistetaan rationaaliluku q yksinkertaisimpaan ! muotoon Eukleideen algoritmilla ! funktion arvo on supistettu rationaaliluku type (rational) simplify type (rational), intent(in):: q integer a, b a=q%nominator b=q%denominator do if (a < b) then c=a; a=b; b=c; end if do while (a >= b) a = a-b end do if (a == 0) exit end do ! b on nyt osoittajan ja nimittajan ! suurin yhteinen tekija simplify%nominator = q%nominator/b simplify%denominator = q%denominator/b end function end modulePakkauksen käyttö:
program koe use ratpack implicit none type (rational) :: p, q, r p%nominator=1; p%denominator=2 q%nominator=3; q%denominator=4 r=add(p,q) write(*,*) r%nominator, r%denominator end program
f95 -o koe koe.f90 ratpack.oKun moduuli on otettu käyttöön use-lauseella, kaikki moduulissa määritellyt tyypit, muuttujat ja proseduurit ovat käytettävissä. Määrittelyt ovat julkisia (public).
Moduulissa voi olla myös yksityisiä (private) määrittelyjä, jotka eivät näy käyttäjälle.
Myös julkisen tietotyypin komponentit voivat olla yksityisiä.
real, private, dimension(100) :: table type rational integer, private :: nominator, denominator end typeKäyttäjä ei pääse suoraan käsiksi tyypin rational komponentteihin. Komponenttien arvojen asettaminen ja tutkiminen on mahdollista vain moduulissa määriteltyjen proseduurien avulla.
Tyypin sisäistä määrittelyä voidaan muuttaa ilman, että se vaikuttaa käyttäjän ohjelmiin. Nimiä voidaan muuttaa tai koko esitystapa vaihtaa.
Käyttäjä ei voi vahingossa sotkea tietorakenteita.
Rationaalilukumoduuliin täytyy lisätä proseduuri, jolla muodostetaan rationaalilukuja:
function rat (n, d) ! muodostetaan rationaaliluku, jonka ! osoittaja=n nimittaja=d type (rational) rat integer, intent(in):: n, d rat%nominator=n rat%denominator=d end functionLisäksi tarvitaan proseduurit, joilla rationaaliluvusta poimitaan osoittaja ja nimittäjä:
function nomin (p) ! palautetaan rationaaliluvun osoittaja integer nomin type (rational), intent(in):: p nomin=p%nominator end function function denom (p) ! palautetaan rationaaliluvun nimittaja integer denom type (rational), intent(in):: p denom=p%denominator end functionNyt rationaaliluvun osoittajaan ja nimittäjään ei voi viitata suoraan, vaan on käytettävä moduulin proseduureja:
program koe use ratpack implicit none type (rational) :: p, q, r p=rat(1, 2) p=rat(3, 4) r=add(p,q) write(*,*) nomin(p), denom(p) end programAritmeettiset operaattorit voidaan määritellä niin, että ne kohdistuvat mielivaltaisiin muuttujatyyppeihin:
type (rational) :: p, q, r ... r=p+qTätä käsitellään myöhemmin.
R2 = \sum | yi - f(xi) | 2
Sovitettava funktio f sisältää muuttujan lisäksi joukon vakioita (parametreja) ak, k=1, ..., K.
Residuaali R on sovitettavan funktion parametrien funktio: R=R(a1, ... , aK). Etsitään sellaiset parametrien arvot, joilla R tulee mahdollisimman pieneksi.
Oletetaan, että f on derivoituva parametrien suhteen. Residuaalin R minimissä on
\d R/ \d a1=0, ... \d R/ \d aK=0.
Tästä saadaan yhtälöryhmä sovitettavassa funktiossa esiintyville parametreille.
Jos funktio f voidaan esittää joidenkin kantafunktioiden fi lineaarikombinaationa
f(x)= \sum ai fi(x),
saadaan lineaarinen yhtälöryhmä riippumatta siitä, mitä muotoa kantafunktiot fi ovat.
Esimerkiksi
f(x) =
a0 + a1 x +
a2 x2,
f(x) =
a1 sin x +
a2 cos x,
f(x) =
a0 +
a1 ex +
a2 e3x.
Johdetaan ratkaisu, kun sovitettava funktio on muotoa
f(x) = a + b x,
eli kantafunktiot ovat 1 ja x.
Minimoitava suure on
R=\sum (yi - a - b xi)2.
Osittaisderivaatat ovat
\dR / \da =
-2\sum (yi - a -
bxi),
\dR / \db =
-2\sum (yi - a -
bxi) xi.
Saadaan normaaliyhtälöt:
\sum yi - a \sum 1 -
b \sum xi = 0,
\sum xi yi -
a \sum xi -
b \sum xi2 = 0.
eli
a N + b Sx = Sy,
a Sx + b Sxx = Sxy
missä
Sx = \sum xi,
Sy = \sum yi,
Sxx = \sum xi2,
Sxy = \sum xi yi.
Datapisteiden koordinaatit ovat yleensä mittaustuloksia, joilla kullakin on oma virheensä.
Kirjoitetaan minimoitava suure muotoon
R2 = \sum ((yi - f(xi) \sigmai)2,
missä \sigmai on havainnon yi virhe.
Jos kaikki virheet \sigmai ovat samoja, tämä poikkeaa aikaisemmasta versiosta vain vakiokertoimella, jolloin normaaliyhtälöiden ratkaisut eivät muutu.
Kun y:n virheet otetaan huomioon, pienimmän neliösumman suoran normaaliyhtälöt ovat:
a S + b Sx = b Sy,
a Sx + b Sxx = Sxy,
missä
S =
\sum (1 / \sigmai2),
Sx =
\sum (xi / \sigmai2),
Sy=
\sum (yi / \sigmai2),
Sxx =
\sum (xi2 /
\sigmai2),
Sxy =
\sum (xi yi /
\sigmai2).
Yleisessä tapauksessa normaaliyhtälöt ovat
\sum (yi - f(xi) / \sigmai2) (\d f(xi) / \d ak=0, k=1,...,K.
Suoran tapauksessa normaaliyhtälöiden ratkaisu on
a = (Sxx Sy -
Sx Sxy / D),
b = (S Sxy -
Sx Sy / D),
missä
D = S Sxy - (Sx)2.
Suoran parametrien hajonnat ovat
\sigmaa = \sqrt( Sxx / D),
\sigmab = \sqrt( S / D).
y(x) = a1\phi1(\x) + ... + aK\phiK(x).
Selitettävän muuttujan y arvoista muodostetaan pystyvektori
y = ( y1, y2, ... yn) T
Muuttujan x arvojen xi avulla lasketaan matriisi
A = \phi1(x1) \phi2(x1) ... \phiK(x1) \phi1(x2) \phi2(x2) ... \phiK(x2) ... ... ... \phi1(xn) \phi2(xn) ... \phiK(xn)Ratkaistavat kertoimet muodostavat pystyvektorin
a = (a1, a2, ... aK)T.
Jotta sovitettava funktio kuvaisi dataa, täytyy olla
A a = y.
Tämä yhtälö voidaan ratkaista täsmällisesti vain, jos A on neliömatriisi, eli havaintoja on yhtä monta kuin kantafunktioita.
Yleisessä tapauksessa voidaan etsiä vektori a, joka antaa minimiarvon normille || A a - y ||.
Pienimmän neliösumman ratkaisu on
Ca = d,
missä
C = AT A
ja
d= AT y
Tämä K:n yhtälön ryhmä on normaaliyhtälöiden matriisimuoto.
Jos mittausten virheet otetaan huomioon
C = AT \Sigma-1 A
d = AT \Sigma-1 y,
missä \Sigma-1 on kovarianssimatriisin käänteismatriisi.
Jos mittaukset ovat riippumattomia, kovarianssimatriisi on
\sigma12 0 ... 0 0 \sigma22 ... 0 ... ... ... 0 0 0 ... \sigman2ja sen käänteismatriisi
1/\sigma12 0 ... 0 0 1/\sigma22 ... 0 ... ... ... 0 0 0 ... 1/\sigman2Jos mittaukset ovat riippumattomia, on
Cij = \suml (\phii(xl) \phij(xl) / \sigmal2).
di = \suml (\phii (xl) yl / \sigmal 2).
Käänteismatriisi C-1 on kovarianssimatriisi, jonka lävistäjältä löytyvät kertoimien varianssit:
\sigma_ai = \sqrt(C-1ii).
Jos C-1 on lävistäjämatriisi, parametrit ovat riippumattomia.
1 1 0.5 3 1 1.0 4 3 0.5 6 4 0.5Sovitetaan tähän suora, jolloin \phi1(x)=1, \phi2(x)=x.
A = 1 1 1 3 1 4 1 6 b = 1 1 3 4
\Sigma = 0.25 0 0 0 0 1 0 0 0 0 0.25 0 0 0 0 0.25 \Sigma-1 = 4 0 0 0 0 1 0 0 0 0 4 0 0 0 0 4
C = AT \Sigma-1 A =
13 47 47 221
d = AT \Sigma-1 y =
33 151Saadaan yhtälöryhmä
| 13 47 | | a | | 33 | | | | | = | | | 47 221 | | b | | 151 |jonka ratkaisu on a=0.295, b=0.620.
Kerroinmatriisin käänteismatriisi on
C-1 =
0.333, -0.071 -0.071 0.020josta
\sigmaa = \sqrt(0.333) = 0.577,
\sigmab = \sqrt(0.020) = 0.140.
On etsittävä matriisi X, jolle
AX = I,
missä I on yksikkömatriisi. Tämä voidaan kirjoittaa n2 lineaarisen yhtälön ryhmäksi.
Jos esimerkiksi n=2, on
| a11 a12 | | x11 x12 | | 1 0 | | | | | = | | | a21 a22 | | x21 x22 | | 0 1 |eli
a11 x11 + a12 x21 = 1, a11 x12 + a12 x22 = 0, a21 x11 + a22 x21 = 0, a21 x12 + a22 x22 = 1.Tästä voidaan ratkaista käänteismatriisin alkiot aikaisemmin esitetyllä lineaarisen yhtälöryhmän ratkaisijalla.
f(x) = a0 + a1x + a2x + ... + anxn.
Polynomi voi käyttäytyä huonosti havaintopisteiden ulkopuolella.
Kun astelukua lisätään, polynomi saadaan kulkemaan kaikkien haluttujen pisteiden kautta, mutta niiden välillä se voi heilahdella voimakkaasti. Usein korkein järkevä asteluku on noin 4--5.
Jos aineistossa on pitkiä aukkoja, sovitettuun käyrään saattaa ilmaantua asiaankuulumattomia mutkia.
Regularisointimenetelmät "jäykistävät" sovitettavaa funktiota ja estävät sen liialliset heilahtelut. Esimerkiksi voidaan rajoittaa korkeimmanasteisten termien kertoimia, mikä merkitsee korkeampien derivaattojen pitämistä pieninä.
Regularisointi voidaan toteuttaa esimerkiksi korvaamalla minimoitava residuaali lausekkeella
\sum (yi - P(xi))2 + \lambda\sum P''(xi)2,
missä \lambda on jokin vakio. Tämän lausekkeen minimointi johtaa ratkaisuun, jossa polynomien toiset derivaatat ovat pieniä, joten käyrässä ei esiinny jyrkkiä mutkia.
Esimerkki: Kuvataan Rungen funktiota 9 pisteellä ja sovitetaan niihin eri asteisia polynomeja:
f(x) = A0 + \sum Ak cos (2\pi kx/P) + \sum Bk sin (2\pi kx/P),
missä P on jakson pituus.
Jos aineisto ei ole tasavälistä, kertoimien laskeminen on hankalaa. Helpoin tapa on ratkaista ongelma pienimmän neliösumman sovituksena. Kantafunktiona ovat sin kx ja cos kx.
Mahdollisia ongelmia:
1) Lineaarisessa sovituksessa jakso on tunnettava etukäteen. Mikäli sekin halutaan sovittaa samanaikaisesti, joudutaan ratkaisemaan epälineaarinen tehtävä.
2) Jos aineisto ei ole tasavälinen, kantafunktiot eivät ole ortogonaalisia. Myös sarjan alkupään kertoimet muuttuvat, jos sarjaan lisätään uusia termejä. Jos sarjalle käytetään aineistosta riippuvaa katkaisukriteeriä (esimerkiksi lisätään termejä, kunnes R ei enää oleellisesti pienene), eri aineistoja ei enää voi luotettavasti vertailla keskenään. Mikäli eri aineistoja halutaan verrata, on jokainen aineisto esitettävä yhtä monella termillä.
3) Aineiston tulisi kattaa ainakin yksi kokonainen jakso, eikä siinä saisi olla pitkiä katkoja. Muuten kertoimien virheet voivat tulla hyvin suuriksi.
4) Jos mitattavassa suureessa esiintyy Nyquistin taajuutta korkeampia taajuuksia, ne voivat aiheuttaa mitattuihin arvoihin matalia taajuuksia, joita todellisuudessa ei ole olemassakaan.
5) Jos aineistossa esiintyy jyrkkiä hyppäyksiä, sarja suppenee niiden lähellä varsin hitaasti.
f(x) = a e-bx,
Sovitetaankin funktion f logaritmi
ln f(x) = a' - bx,
missä a'=ln a. Tuloksena on lineaarinen tehtävä.
Mikäli sovitettavan funktion derivaatat parametrien suhteen pystytään laskemaan, voidaan parametreille johtaa yhtälöryhmä, kuten lineaarisessakin tapauksessa. Yhtälöryhmä on kuitenkin epälineaarinen.
Jos derivaattoja ei pystytä laskemaan analyyttisesti, tai jos tuloksena on kovin mutkikas yhtälöryhmä, on helpompaa käyttää jotakin minimointiohjelmaa.