fft.pl
author A.M. Thurnherr <athurnherr@yahoo.com>
Tue, 05 Jun 2012 01:28:22 +0000
changeset 1 d17eb00c168b
parent 0 a5233793bf69
child 20 7ea1fd9d64e6
permissions -rw-r--r--
.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     1
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     2
#                    F F T . P L 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#                    doc: Fri Mar 12 09:20:33 1999
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     4
#                    dlm: Mon Jul 24 14:58:04 2006
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 1999 A.M. Thurnherr
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     6
#                    uE-Info: 241 36 NIL 0 0 72 66 2 4 NIL ofnI
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     7
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     8
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     9
# Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
#	It was found when rotary-analysing the FLAME current meters that
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
#	the sign of the frequencies returned was wrong. When investigating
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
#	the problem it was found that there are two conventions, one called
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
#	the engineering convention which is followed by Bendat & Piersol
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
#	[1971], Gonella [1972], and Mooers [1973] but not Numerical Recipes.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
#	For real-valued functions it does not matter because the power
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    16
#	of the positive and negative frequencies are summed. The engineering
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    17
#	convention appears more sensible, however, because it actually leads
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    18
#	to the anticlockwise component to be reported as positive frequencies
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    19
#	which is consistent with exp(i phi) = cos phi + i sin phi and the
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    20
#	usual axes orientations.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
# HISTORY:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
#	Mar 12, 1999: - adapted from NR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#	Mar 13, 1999: - ``perlified'' (0-relative arrays; return value)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    25
#	Mar 14, 1999: - cosmetic changes
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
#	Mar 15, 1999: - pad initial/final NaN values with 0es
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
#	Dec 08, 1999: - adapted for complex FFT
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
#	Dec 09, 1999: - continued
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
#	Dec 10, 1999: - BUG: < replaced by <= (no difference)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
#	Dec 11, 1999: - investigated wrong frequency sign
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
#	Dec 14, 1999: - changed one-sided spectra to get half of the f=0 power
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
#	Mar 04, 2000: - require mean-removal when zero-padding is used
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    33
#				  - BUG (cosmetic)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
#	Mar 05: 2000: - BUG: died even if no padding was done
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    35
#	Mar 08, 2000: - removed opt_r hard-coding
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    36
#	May 02, 2001: - BUG: RMS was really standard deviation estimator
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    37
#	Aug 29, 2003: - BUG: &icFFT did not calc sigma correctly whenever
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
#						 infield == outfield (e.g. [fftfilt] w/o -f)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
#	Mar 31, 2004: - added cFFT_bufR()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
#	Feb  9, 2005: - added &phase_pos(), &phase_neg()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
#   Jul  1, 2006: - Version 3.3 [HISTORY]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
#   Jul 24, 2006: - modified to use $PRACTICALLY_ZERO
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    43
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    44
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    45
# FOUR1 routine
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
# Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
#	- nan will abort FFT!
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
#	- added power of two assertions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
#	- arrays are 0-relative
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
#	- isig should be set to -1 for FFT and to 1 for reverse FFT (see
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
#	  note above)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
sub FOUR1($@) # ($isign, @data) => @fourier coefficients
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
	my($isign,@data) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
	my($n,$mmax,$m,$j,$istep,$i);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
	my($wtemp,$wr,$wpr,$wpi,$wi,$theta);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
	my($tempr,$tempi);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
	my($N) = @data / 2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
	$n = $N << 1;										# re-order input
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
	$j = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
	for ($i=0; $i<$n-1; $i+=2) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
		if ($j > $i) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
			$tempr = $data[$j];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
			$tempi = $data[$j+1];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
			$data[$j]   = $data[$i];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
			$data[$j+1] = $data[$i+1];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
			$data[$i]   = $tempr;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
			$data[$i+1] = $tempi;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
        }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
        croak("$0 (fft.pl) $N is not a power of two\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
        	if ($n % 2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
		$m = $n >> 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
		while ($m >= 2 && $j >= $m) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
			$j -= $m;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
			croak("$0 (fft.pl) $N is not a power of two\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
	            if ($m % 2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
			$m >>= 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
		$j += $m;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    85
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
#	for ($i=0; $i<=$#data; $i+=2) {						# dump data
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
#		print(STDERR "$data[$i]$opt_O$data[$i+1]$opt_R")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
#	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
	$mmax = 2;											# do FFT
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
	while ($n > $mmax) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
		$istep = $mmax << 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
		$theta = $isign*(6.28318530717959/$mmax);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
		$wtemp = sin(0.5*$theta);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
		$wpr   = -2.0*$wtemp*$wtemp;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
		$wpi   = sin($theta);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
		$wr    = 1.0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
		$wi    = 0.0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
		for ($m=0; $m<$mmax-1; $m+=2) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
			for ($i=$m; $i<=$n-1; $i+=$istep) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
				$j     = $i + $mmax;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
				$tempr = $wr*$data[$j]   - $wi*$data[$j+1];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
				$tempi = $wr*$data[$j+1] + $wi*$data[$j];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
				$data[$j]    = $data[$i]   - $tempr;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
				$data[$j+1]  = $data[$i+1] - $tempi;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
				$data[$i]   += $tempr;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
				$data[$i+1] += $tempi;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
			$wtemp = $wr;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
			$wr    = $wr*$wpr - $wi*$wpi    + $wr;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   112
			$wi    = $wi*$wpr + $wtemp*$wpi + $wi;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   113
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   114
		$mmax = $istep;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   115
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   116
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   117
	return @data;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   118
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   119
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   120
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   121
# TWOFFT routine
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   122
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   123
# Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   124
#	- arrays are 0-relative
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   125
#	- array references are used throughout; input arrays are 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   126
#     in $ants_[][] style; ouput are simple arrays
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   127
#	- isign convention of NR is used here!!!
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   128
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   129
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   130
sub TWOFFT($$$$$$)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   131
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   132
	my($data1R,$fnr1,$data2R,$fnr2,$fft1R,$fft2R) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   133
	my($nn3,$nn2,$jj,$j);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   134
	my($rep,$rem,$aip,$aim);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   135
	my($n) = scalar(@{$data1R});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   136
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   137
	$nn3 = 1 + ($nn2 = 2 + $n + $n);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   138
	for ($j=1,$jj=2; $j<=$n; $j++,$jj+=2) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   139
		$fft1R->[$jj-2] = $data1R->[$j-1][$fnr1];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   140
		$fft1R->[$jj-1] = $data2R->[$j-1][$fnr2];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   141
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   142
	@{$fft1R} = FOUR1(1,@{$fft1R});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   143
	$fft2R->[0] = $fft1R->[1];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   144
	$fft1R->[1] = $fft2R->[1] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   145
	for ($j=3; $j<=$n+1; $j+=2) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   146
		$rep = 0.5 * ($fft1R->[$j-1] + $fft1R->[$nn2-$j-1]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   147
		$rem = 0.5 * ($fft1R->[$j-1] - $fft1R->[$nn2-$j-1]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   148
		$aip = 0.5 * ($fft1R->[$j] + $fft1R->[$nn3-$j-1]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   149
		$aim = 0.5 * ($fft1R->[$j] - $fft1R->[$nn3-$j-1]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   150
		$fft1R->[$j-1] = $rep;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   151
		$fft1R->[$j]   = $aim;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   152
		$fft1R->[$nn2-$j-1] =  $rep;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   153
		$fft1R->[$nn3-$j-1] = -$aim;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   154
		$fft2R->[$j-1] =  $aip;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   155
		$fft2R->[$j]   = -$rem;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   156
		$fft2R->[$nn2-$j-1] = $aip;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   157
		$fft2R->[$nn3-$j-1] = $rem;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   158
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   159
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   160
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   161
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   162
# Interface to @ants_
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   163
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   164
# Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   165
#	- N (number of complex samples) calculated as next larger pwr-of-two
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   166
#	  if set to 0 on calling; otherwise set is used
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   167
#	- @ants_ padded with 0es to $N (deprecated in Hamming [1989])
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   168
#	- ditto initial and final missing values
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   169
#	- set ifnr to nan if input is purely real
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   170
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   171
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   172
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   173
sub cFFT($$$) { return cFFT_bufR(\@ants_,@_); }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   174
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   175
sub cFFT_bufR($$$) # ($bufR, $rfnr, $ifnr, [$N]) => @coeff
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   176
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   177
	my($bufR,$fnr,$ifnr,$N) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   178
	my(@data,$i,$lastSet);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   179
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   180
	unless ($N) {									# $N not set
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   181
		for ($N=1; $N <= $#ants_; $N <<= 1) {}		# next greater pwroftwo
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   182
		&antsInfo("(fft.pl) N set to $N")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   183
			unless ($N == $#ants_+1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   184
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   185
	for ($i=0; $i<$N && $i<=$#ants_; $i++) {		# PAD
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   186
		last if (numberp($bufR->[$i][$fnr]) &&
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   187
				 (isnan($ifnr) || numberp($bufR->[$i][$ifnr])));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   188
		$data[2*$i]   = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   189
		$data[2*$i+1] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   190
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   191
	$lastSet = $i - 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   192
	&antsInfo("(fft.pl) WARNING: $i initial non-numbers padded with 0es!!!"),
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   193
		$padded=1 if ($i);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   194
	while ($i<$N && $i<=$#ants_) {					# fill
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   195
		$i++,next unless (numberp($bufR->[$i][$fnr]) &&	# skip non-numbers 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   196
				          (isnan($ifnr) || numberp($bufR->[$i][$ifnr])));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   197
		croak("$0: (fft.pl) $lastSet, $i can't handle missing values ($bufR->[$lastSet+1][$fnr])!\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   198
			if ($lastSet != $i-1);					# missing values
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   199
		$data[2*$i]   = $bufR->[$i][$fnr];			# real
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   200
		$data[2*$i+1] = isnan($ifnr) ? 0 : $bufR->[$i][$ifnr];	# imag
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   201
		$lastSet = $i;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   202
		$i++;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   203
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   204
	&antsInfo("(fft.pl) WARNING: %d final non-numbers padded with 0es!!!",$i-$lastSet-1),
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   205
		$padded=1 if ($i > $lastSet+1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   206
	&antsInfo("(fft.pl) WARNING: padded with %d 0es to next pwr-of-two!!!",$N-$i),
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   207
		$padded=1 if ($i < $N);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   208
	croak("$0: (fft.pl) refusing to pad with zeroes unless mean is removed (sorry)\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   209
		if ($padded && !$FFT_ALLOW_ZERO_PADDING);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   210
	$i = $lastSet + 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   211
	while ($i < $N) {								# PAD
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   212
		$data[2*$i]   = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   213
		$data[2*$i+1] = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   214
		$i++;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   215
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   216
	return &FOUR1(-1,@data);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   217
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   218
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   219
sub icFFT($$@) # ($ofnr, $tfnr, @coeff) => sigma
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   220
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   221
	my($ofnr,$tfnr,@coeff) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   222
	my($N) = ($#coeff+1)/2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   223
	my(@val) = &FOUR1(1,@coeff);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   224
	my($i);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   225
	my($n) = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   226
	my($sumsq) = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   227
	my($mai) = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   228
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   229
	for ($i=0; $i<$N && $i<=$#ants_ ; $i++) {		# fill
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   230
		my($oldval) = $ants_[$i][$ofnr];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   231
		push(@{$ants_[$i]},nan)						# pad empty fields
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   232
			while ($#{$ants_[$i]} < $tfnr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   233
		$ants_[$i][$tfnr] = $val[2*$i]/$N;			# real
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   234
		$mai = abs($val[2*$i+1])					# imag
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   235
			if (abs($val[2*$i+1]) > $mai);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   236
		next unless (numberp($oldval));	# sigma
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   237
		$sumsq += ($oldval - $ants_[$i][$tfnr])**2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   238
		$n++;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   239
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   240
	&antsInfo("(fft.pl) WARNING: imaginary exponents (abs <= $mai) ignored")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   241
		if ($mai > $PRACTICALLY_ZERO);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   242
	&antsInfo("(fft.pl) WARNING: reducing data (%d -> %d)",$#ants_+1,$N)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   243
		if ($i <= $#ants_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   244
	while ($i <= $#ants_) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   245
		$ants_[$i][$fnr] = nan;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   246
		$i++;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   247
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   248
    return ($n > 1) ? sqrt($sumsq/($n-1)) : nan;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   249
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   250
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   251
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   252
# Periodogram (p.421; (12.7.5) -- (12.7.6))
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   253
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   254
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   255
# Miscellaneous Notes:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   256
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   257
# - there are N/2 + 1 values in the (unbinned) PSD (see NR)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   258
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   259
# Notes regarding the effects of zero padding:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   260
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   261
# - using zero-padding on a time series where the mean is not removed
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   262
#	can result in TOTALLY DIFFERENT RESULTS, try it e.g. with
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   263
#	temperatures!!! (A moment's thought will reveal why)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   264
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   265
# - Because the total power is normalized to the mean squared amplitude
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   266
#	0-padded values depress the power; this was taken care of below by
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   267
#	normalizing the power by multiplying it with nrm=(nData+nZeroes)/nData;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   268
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   269
# - this was checked using `avg -m' (in case of complex input the total
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   270
#	power is given by sqrt(Re**2+Im**2));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   271
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   272
# - if zero-padding is used sqrt(nrm*P[0]) is mean value (done in [pgram])
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   273
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   274
# Notes on interpreting the power spectrum (Hamming [1989] & NR):
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   275
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   276
# - the frequency spectrum encompasses the frequencies between 0 (the
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   277
#	mean value) and the Nyquist frequency (1 / (2 x sampling interval))
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   278
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   279
# - higher frequencies are aliased into the power spectrum in a mirrored
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   280
#   way (e.g. noise tends to (linearly?) approach zero as f goes to inft;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   281
#   the downsloping spectrum `hits' the Nyquist frequency, turns around
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   282
#   and continues falling towards the zero frequency, where it gets mirrored
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   283
# 	again => spectrum flattens towards Nyquist frequency
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   284
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   285
# - the sum over all P's (total power) is equal to the mean square value;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   286
#	when one-sided spectra are used, P[0] and P[N/2] are counted doubly
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   287
#	and must be subtracted from the total; NB: the total power is reduced
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   288
#	if data are padded with 0es
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   289
#   
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   290
# - sqrt(P[0]) is an estimate for the mean value which is only accurate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   291
#   if no zero-padding is perfomed; removing the mean will
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   292
#	strongly change the spectrum near the origin which might
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   293
#   or might not be a good thing, depending on the physics behind it (e.g.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   294
#	it makes sense to remove the mean if a power spectrum from a temperature
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   295
#	record is calculated but not if flow velocity is used).
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   296
#   Removing higher order trends will also affect the spectrum but not
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   297
#   in such a simple fashion. Note that the problem is mainly restricted
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   298
#   to cases where the signal is in the low frequency and thus affected
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   299
#	by the strong changes in the spectrum there.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   300
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   301
# Notes on the two-sided spectra:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   302
# - the power of the mean flow (sqrt(P[0])) is non-rotary. To have the sum
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   303
#	of both one-sided spectra equal the two-sided one, each one-sided
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   304
#	spectrum gets half of the total value.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   305
# - the same is true for the highest frequency; at the Nyquist frequency
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   306
#	every rotation is sampled exactly twice => polarization cannot be
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   307
#	determined (imagine a wheel with one spoke...)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   308
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   309
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   310
sub pgram_onesided(@) # $nData,@C -> return @P
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   311
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   312
	my($nData,@C) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   313
	my($N)    = ($#C+1) / 2;				# number of fourier comps
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   314
	my($Pfac) = $N**(-2) * $N/$nData;		# normalized to mean-sq amp
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   315
	my($k,@P);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   316
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   317
	$P[0] = $Pfac * ($C[0]**2 + $C[1]**2);	# calc periodogram
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   318
	for ($k=1; $k<=$N/2-1; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   319
		$P[$k] = $Pfac * ($C[2*$k]**2 + $C[2*$k+1]**2 +
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   320
						  $C[2*($N-$k)]**2 + $C[2*($N-$k)+1]**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   321
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   322
	$P[$N/2] = $Pfac * ($C[2*($N/2)]**2 + $C[2*($N/2)+1]**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   323
	return @P;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   324
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   325
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   326
sub pgram_pos(@) # $nData,@C -> return @P
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   327
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   328
	my($nData,@C) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   329
	my($N)    = ($#C+1) / 2;				# number of fourier comps
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   330
	my($Pfac) = $N**(-2) * $N/$nData;		# normalized to mean-sq amp
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   331
	my($k,@P);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   332
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   333
	$P[0] = 0.5 * $Pfac * ($C[0]**2 + $C[1]**2);	# calc periodogram
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   334
	for ($k=1; $k<=$N/2-1; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   335
		$P[$k] = $Pfac * ($C[2*$k]**2 + $C[2*$k+1]**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   336
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   337
	$P[$N/2] = 0.5 * $Pfac * ($C[2*($N/2)]**2 + $C[2*($N/2)+1]**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   338
	return @P;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   339
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   340
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   341
sub pgram_neg(@) # $nData,@C -> return @P
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   342
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   343
	my($nData,@C) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   344
	my($N)    = ($#C+1) / 2;				# number of fourier comps
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   345
	my($Pfac) = $N**(-2) * $N/$nData;		# normalized to mean-sq amp
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   346
	my($k,@P);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   347
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   348
	$P[0] = 0.5 * $Pfac * ($C[0]**2 + $C[1]**2);	# calc periodogram
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   349
	for ($k=1; $k<=$N/2-1; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   350
		$P[$k] = $Pfac * ($C[2*($N-$k)]**2 + $C[2*($N-$k)+1]**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   351
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   352
	$P[$N/2] = 0.5 * $Pfac * ($C[2*($N/2)]**2 + $C[2*($N/2)+1]**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   353
	return @P;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   354
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   355
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   356
#------------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   357
# Current Ellipses (Emery and Thomson, 5.6.4.2 (Rotary Component Spectra)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   358
#------------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   359
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   360
# Notes on phase (ellipsis inclination) calculations:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   361
#	- comparing equations 5.6.42 and 5.6.43 in E+T shows a sign
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   362
#	  sign change of one of the terms (U_2k - V_1k in eqn 5.6.42a)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   363
#	- for reasons of symmetry, this is unlikely to be correct
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   364
#	- in order to test this, I compared the M2 ellipses inclinations of
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   365
#	  a tidal analysis of BBTRE instruments #1 & #3 with the output
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   366
#	  and found that changing the sign in 5.6.43a brought the values
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   367
#	  into agreement (#1: tidal analysis 155+-3, pgram -25; #3: 136+-5,
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   368
#	  pgram -44)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   369
#	- the changes are marked in the code by a (superfluous) + sign
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   370
#	- the sign change was later found to be consistent with the
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   371
#	  tidal analysis package manual by MGG Foreman (p.11)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   372
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   373
sub phase_pos(@) # @C -> return @eps
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   374
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   375
	my(@C) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   376
	my($N) = ($#C+1) / 2;				# number of fourier comps
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   377
	my($k,@eps);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   378
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   379
	$eps[0] = 180 / $PI * atan2(+$C[1],$C[0]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   380
	for ($k=1; $k<=$N/2-1; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   381
		$eps[$k] = 180 / $PI * atan2(+$C[2*$k+1],$C[2*$k]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   382
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   383
	$eps[$N/2] = 180 / $PI * atan2(+$C[2*($N/2)+1],$C[2*($N/2)]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   384
	return @eps;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   385
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   386
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   387
sub phase_neg(@) # @C -> return @P
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   388
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   389
	my(@C) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   390
	my($N) = ($#C+1) / 2;				# number of fourier comps
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   391
	my($k,@P);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   392
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   393
	$eps[0] = 180 / $PI * atan2(+$C[1],$C[0]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   394
	for ($k=1; $k<=$N/2-1; $k++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   395
		$eps[$k] = 180 / $PI * atan2(+$C[2*($N-$k)+1],$C[2*($N-$k)]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   396
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   397
	$eps[$N/2] = 180 / $PI * atan2(+$C[2*($N/2)+1],$C[2*($N/2)]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   398
	return @eps;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   399
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   400
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   401
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   402
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   403
1;