#!/usr/bin/perl use Math::Trig; # Script integrates data of input file using trapezoid or simpsons rule # default range is equal to the range of input file. Alternatively, one can set # integration limits by -xa:b, for example -x-1:1 # Usage is very similar to usage of strans routine. Few examples are: # intg '#1' '#2' datafile # intg -x-1:1 -simpson '#1' '#2/2' '#3*2' data* # intg '#1' 'sqrt(#2**2+#3**2)' '#4' data* $stdin = -t STDIN; if ($stdin ne "1") { open(G, ">integ.stdin"); while () { print G $_; } close(G); $ARGV[$#ARGV + 1] = "integ.stdin"; } $r_n = "-?[0-9]+\.?[0-9]*[e|E]?-?[0-9]*"; $pat_borders = "-x($r_n):($r_n)"; $trapez = 1; foreach $_ (@ARGV) { if (/\#/) { push(@argum,$_); } elsif(/simpson/){ $simpson = 1; $trapez=0; } elsif(/$pat_borders/) { $xstart = $1; $xend = $2; } else { push(@filen,$_); } } # print "$#argum\n\n"; if (not defined @argum) { @argum = ("\#1","\#2"); } foreach $col (@argum) { $col =~ s/#(\d+)/\$spl\[${\($1-1)}\]/g; } $first = shift @argum; $fn=0; foreach $f (@filen) { open (G, "<$f"); $i=0; while () { if (/^\#/){} else{ @spl = split(' ', $_); push(@omega, eval $first); $j=0; foreach $col (@argum) { $values[$j++][$i] = eval $col; } $i++; } } if (defined $xstart){ if ($xstart<=$omega[0]){ undef $xstart; $istart = -1; } else { $l=0; while ($omega[$l+1]<$xstart && $l<$#omega) { $l++; } $istart = $l; } } else { $istart = -1; } if (defined $xend){ if ($xend>=$omega[$#omega]){ undef $xend; $iend = $#omega+1; } else { $l=0; while ($omega[$l]<$xend && $l<$#omega) { $l++; } $iend = $l; } } else { $iend = $#omega+1; } if ($trapez){ for ($h=0; $h<$j; $h++) { if ($istart+1 == $iend) { $wx = 0.5*($xend-$xstart)/($omega[$iend]-$omega[$istart]); $w1 = $values[$h][$istart]*(2*$omega[$iend]-$xstart-$xend); $w2 = $values[$h][$iend]*($xstart+$xend-2*$omega[$istart]); $sum[$h] += $wx*($w1+$w2); } else { if (defined $xstart){ $x0 = $omega[$istart]; $x1 = $omega[$istart+1]; $g0 = 0.5*($x1-$xstart)*($x1-$xstart)/($x1-$x0); $g1 = 0.5*($x1-$xstart)*($x1+$xstart-2*$x0)/($x1-$x0); $sum[$h] += $values[$h][$istart]*$g0+$values[$h][$istart+1]*$g1; } for ($k=$istart+1; $k<$iend-1; $k++) { $deps = 0.5*($omega[$k+1]-$omega[$k]); $sum[$h] += ($values[$h][$k+1]+$values[$h][$k])*$deps; } if (defined $xend){ $x0 = $omega[$iend-1]; $x1 = $omega[$iend]; $g0 = 0.5*($xend-$x0)*(2*$x1-$xend-$x0)/($x1-$x0); $g1 = 0.5*($xend-$x0)*($xend-$x0)/($x1-$x0); $sum[$h] += $values[$h][$iend-1]*$g0+$values[$h][$iend]*$g1; } } } } if ($simpson){ for ($k=1; $k<$i-1; $k+=2) { $h1 = $omega[$k]-$omega[$k-1]; $h2 = $omega[$k+1]-$omega[$k]; $a = ($h1+$h2)*(2*$h1-$h2)/(6*$h1); $b = ($h1+$h2)*($h1+$h2)*($h1+$h2)/(6*$h1*$h2); $c = ($h1+$h2)*(2*$h2-$h1)/(6*$h2); for ($h=0; $h<$j; $h++) { $sum[$h] += $a*$values[$h][$k-1]+$b*$values[$h][$k]+$c*$values[$h][$k+1]; } } } # print "$fn "; for ($h=0; $h<$j; $h++) { print "$sum[$h] "; } print "\n"; undef @omega; undef @sum; $fn++; } qx{rm -f integ.stdin}; sub ferm{ return 1.0/(exp(@_[0])+1); }