Perl ja fresnelin integraalit

Fresnelin integraalit (kts. wiki) voi toki laskea perlin liitännäisen avullakin mutta jos liitännäistä ei ole, niin saahan perl-ohjelmaan octave:n käskyjä system käskyn avulla. Octave on matematiikkaohjelma vrt. Matlab. Octave pitää olla koneella asennettuna.

Tämäkin vain osoittaa miten monipuolinen ohjelmointikieli perl onkaan.

Hieman pitkä ja kömpelö tämä on mutta kun system käsky ei palauta muuta kuin sen onnistuiko operaatio, joten aputiedostoilta ei voinut välttyä.

#!/usr/local/bin/perl #fresnelin integraalit perl-insertteinä
$x=0.2;
$fs=&fs($x); #fresnel S(x)
$fc=&fc($x); #fresnel C(x)
print "fs=$fs fc=$fc\n";

sub fs #fresnel S(x) funktion laskeminen alirutiinina
{
$m=chr(59); #puolipiste ascii=59
$statement="fresnelS(".$x.") ".$m."\n save -ascii 'apu.dat'".$m; #suoritettavat käskyt (octave-kieltä)
$fs=&lasku($statement);
return $fs;
}

sub fc #fresnel C(x) funktion laskeminen alirutiinina
{
$m=chr(59); #puolipiste ascii=59
$statement="fresnelC(".$x.") ".$m."\n save -ascii 'apu.dat'".$m;
$fc=&lasku($statement);
return $fc;
}

sub lasku #octave ohjelman suoritus
{
open (FH1,'>',"f.m"); #avataan tiedosto kirjoitettavaksi
print FH1 $statement; #kirjoitetaan käskyt tiedostoon fs.dat
close (FH1); #suljetaan tiedosto
@args = ("octave -q f.m");
system(@args); #suoritetaan ohjelma
open (FH2,'
2322
Äänestä

Muut lukivat myös

Vastaukset 2

Vanhimmat

Perl-skripti on hieman kömpelö, tässä parempi. Huom: yksi aliohjelma tekee nyt kaiken.


#!/usr/local/bin/perl #Fresnelin integraalit
$t=10;
($fs,$fc)=&fresnel($t); #aliohjelma palauttaa kaksi muuttujaa
print "$fs $fc \n";

sub fresnel #Fresnelin integraalit
{
local($a, $d, @fres); #paikalliset muuttujat
system ("echo 'F = [fresnelC(".$t.");fresnelS(".$t.")];save -ascii 'apu.dat' F;'>f.m"); #octave-skriptin laatiminen
system ("octave -q f.m>NULL"); #octave ohjelman suoritus. NULL poistaa turhat rivinvaihdot
open (FH2,"apu.dat"); #luetaan vastaus tiedostosta apu.dat
$d= -s "apu.dat"; #tiedoston koko
read FH2,$a,$d; #luetaan tiedoston sisalto muuttujaan $a
close (FH2);
@fres = split(/ /,$a); #Kaksi muuttujaa erotetaan toisistaan, erottimena valilyonti
system ("rm apu.dat f.m"); #poistetaan kaytetyt aputiedostot
return $fres[2] 0,$fres[1] 0; #palauttaa muuttujat ja poistaa rivinvaihdon lopusta
}

Äänestä

Edellä mainittu ohjelma perustuu numeeriseen integrointiin. Octave laskee sen ilmeisesti Simpsonin kaavalla (joka on aika tarkka) varsin monella laskentavälillä. Mutta numeerinen integrointi on epätyylikästä (hidasta) ja oikeastaan myös konekieliset insertit. Onneksi Fresnelin integraalit voi laskea myös potenssisarjakehitelmällä, joka mahtuu yhteen perl-skriptitiedostoon. Mitä suurempi on x:n arvo sitä enemmän tarvitaan potenssisarjan alkioita. Seuraava ohjelma antaa luotettavia arvoja KUN x ON ENINTÄÄN 5.2. x:n pitää olla positiivinen. Huomaa häntärekursion käyttö perlissä kertoman laskemisessa.

#!/usr/local/bin/perl #Fresnelin sini ja kosini-integraalit laskettuna potenssisarjakehitelmien avulla.
#fs(x)=$x**(4*$n 3)/((4*$n 3)*(2*$n 1)!) #sini potenssisarjan alkio.
#fc(x)=$x**(4*$n 1)/((4*$n 1)*(2*$n)!) #kosini potenssisarjan alkio. (http://fi.wikipedia.org/wiki/Fresnelin_integraalit)
$x = 0.5; #x:n arvo
$alkioita=90; #mitä suurempi on x:n arvo, sitä enemmän tarvitaan potenssisarjan alkioita tarkan tuloksen saamiseen.
$fcos=&fcos($x);$fsin=&fsin($x);
print "fcos=$fcos\n"; #fresnelin kosini-integraali, lopullinen tulos.
print "fsin=$fsin\n"; #fresnelin sini-integraali, lopullinen tulos.

sub fcos { #fresnelin kosini-integraali.
for (my $n = 0, $fcos = 0;$n < $alkioita;$n ){ #n=potenssisarjan alkion järjestysnumero
$fcos = $fcos $x**(4 * $n 1) / &kertoma((4 * $n 1),(2 * $n));
print "$fcos $n\n"; #tulostaa välituloksen jotka tarkentuvat koko ajan. Näin tuloksen tarkkuus voidaan todeta.
$n ;
$edellinen=$fcos;
$fcos = $fcos - $x**(4 * $n 1) / &kertoma((4 * $n 1),(2 * $n));
my $b=abs($fcos-$edellinen); #kuinka suuren muutoksen potenssisarjan alkio sai aikaan?
if ($b==0){
print "$n alkiota\n";
goto valmis;} #kun muutos hukkuu laskentaepätarkkuuteen, tulos on valmis.
}
valmis:
return $fcos;
}

sub fsin { #fresnelin sini-integraali.
for (my $n = 0,$fsin = 0;$n < $alkioita;$n ){
$fsin = $fsin $x**(4 * $n 3) / &kertoma((4 * $n 3),(2 * $n 1));
print "$fsin $n\n"; #tulostaa välituloksen.
$n ;
$edellinen=$fsin;
$fsin = $fsin - $x**(4 * $n 3) / &kertoma((4 * $n 3),(2 * $n 1));
my $b=abs($fsin-$edellinen); #kuinka suuren muutoksen potenssisarjan alkio sai aikaan?
if ($b==0){
print "$n alkiota\n";
goto valmis;} #kun muutos hukkuu laskentaepätarkkuuteen, tulos on valmis.
}
valmis:
return $fsin;
}

sub kertoma { #Kertoman laskeminen häntärekursion avulla.(http://www.cs.helsinki.fi/u/lmpauvin/ohpe-perl/)
my $yhteensa = shift; my $n = shift; # otetaan talteen parametrit
if ($n == 0) { # jos laskutoimitus on valmis, palautetaan tulos
return $yhteensa;
}
else {
@_ = ($n * $yhteensa, $n - 1); # päivitetään parametrit
goto &kertoma; # kutsutaan aliohjelmaa uudelleen "häntärekursiivisesti"
}
}

Äänestä

Kommentoi aloitusta


Matti.W kirjoitti:

Fresnelin integraalit (kts. wiki) voi toki laskea perlin liitännäisen avullakin mutta jos liitännäistä ei ole, niin saahan perl-ohjelmaan octave:n käskyjä system käskyn avulla. Octave on matematiikkaohjelma vrt. Matlab. Octave pitää olla koneella asennettuna.

Tämäkin vain osoittaa miten monipuolinen ohjelmointikieli perl onkaan.

Hieman pitkä ja kömpelö tämä on mutta kun system käsky ei palauta muuta kuin sen onnistuiko operaatio, joten aputiedostoilta ei voinut välttyä.

#!/usr/local/bin/perl #fresnelin integraalit perl-insertteinä
$x=0.2;
$fs=&fs($x); #fresnel S(x)
$fc=&fc($x); #fresnel C(x)
print "fs=$fs fc=$fc\n";

sub fs #fresnel S(x) funktion laskeminen alirutiinina
{
$m=chr(59); #puolipiste ascii=59
$statement="fresnelS(".$x.") ".$m."\n save -ascii 'apu.dat'".$m; #suoritettavat käskyt (octave-kieltä)
$fs=&lasku($statement);
return $fs;
}

sub fc #fresnel C(x) funktion laskeminen alirutiinina
{
$m=chr(59); #puolipiste ascii=59
$statement="fresnelC(".$x.") ".$m."\n save -ascii 'apu.dat'".$m;
$fc=&lasku($statement);
return $fc;
}

sub lasku #octave ohjelman suoritus
{
open (FH1,'>',"f.m"); #avataan tiedosto kirjoitettavaksi
print FH1 $statement; #kirjoitetaan käskyt tiedostoon fs.dat
close (FH1); #suljetaan tiedosto
@args = ("octave -q f.m");
system(@args); #suoritetaan ohjelma
open (FH2,'

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu