Perl ja fresnelin integraalit

Matti.W

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,'

2

276

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • 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
      }

    • 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"
      }
      }

    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Epäily: Räppäri yritti tappaa vauvansa.

      https://www.mtvuutiset.fi/artikkeli/epaily-mies-yritti-tappaa-vauvansa/9300728 Tämä on erittäin järkyttävä teko täysin p
      Maailman menoa
      45
      4980
    2. Onko Sanna menossa Ukrainaan viettämään vuosipäivää?

      Kun on bongattu Varsovan lentokentältä?
      Maailman menoa
      112
      1560
    3. Räppäri kuoli vankilassa

      Ei kuulemma ole tapahtunut rikosta. Sama vahinkohan kävi Epsteinille. https://www.hs.fi/suomi/art-2000011840869.html "
      Maailman menoa
      48
      1089
    4. Aleksi Rytilä

      Räppäri saa haluamaansa julkisuutta.
      Kotimaiset julkkisjuorut
      13
      1033
    5. 81-vuotias Frederik avoimena - Ei omasta mielestä kelpaa tästä syystä realityihin: "Veemäinen..."

      Junttidiscon kuninkaana tunnettu Frederik, 81, on esiintymislavoilla suvereeni tekijä. Mies on viihdyttänyt ympäri Suome
      Suomalaiset julkkikset
      17
      987
    6. Muusikko yritti tappaa kaksiviikkoisen vauvan

      Karu epäily: Muusikko, 32, yritti tappaa kaksiviikkoisen vauvan Oulussa. IS:n selvityksen perusteella miestä ei ole syy
      Maailman menoa
      75
      940
    7. Välillä kyllä tuntuu, että jaat vihjeitä

      Mutta miten niistä voi olla ollenkaan varma? Ja minä saan niistä kimmokkeen luulemaan yhtä sun toista. Eli mitä ajatella
      Ikävä
      8
      897
    8. Kulukusuunnat

      Eikö kuhmolaiset iha oikiasti tiiä kumpi o vasen ja kumpi oikia? Tuolla ku liikennemerkissä näkyy nuolet ylös ja alas, v
      Kuhmo
      2
      832
    9. Tynkä Eläintarha ei ole enää visiitin väärti

      Ähtärin MesiZoo on vajonnut alas. Näytillä olevien eläinten määrä on romahtanut lähemmäs -40%. Paikat ovat päässeet pah
      Ähtäri
      55
      742
    10. Junan alle

      Kuka päätti tai yritti päättää päivänsä jäämällä junan alle ja aiheutti sen takia veturikuskille ja muille traumat..?
      Kajaani
      27
      713
    Aihe