libfuns.pl
author Andreas Thurnherr <ant@ldeo.columbia.edu>
Mon, 27 Jun 2022 19:05:35 -1000
changeset 51 14ce2387de5e
parent 36 04e8cb4f8073
permissions -rw-r--r--
improved libSBE.pl
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
#                    L I B F U N S . P L 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#                    doc: Wed Mar 24 11:49:13 1999
51
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
     4
#                    dlm: Sat Jun 25 21:11:48 2022
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 1999 A.M. Thurnherr
51
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
     6
#                    uE-Info: 20 34 NIL 0 0 70 2 2 4 NIL ofnI
0
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
# HISTORY:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
#	Mar 24, 1999: - copied from the c-version of NR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
#	Mar 26, 1999: - added stuff for better [./fit]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
#	Sep 18, 1999: - argument typechecking
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
#	Oct 04, 1999: - added gauss(), normal()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
#	Jan 25, 2001: - added f(), sgn()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
#	Apr 16, 2010: - added sinc()
3
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    16
#	Sep  7, 2012: - added acosh()
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
    17
#	Jun  4, 2015: - added gaussRand()
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
    18
#			 	  - made normal() more efficient
36
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    19
#	May 11, 2018: - added Nsq()
51
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    20
#	Jun 25, 2022: - added interp()
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
require	"$ANTS/libvec.pl";								# rad()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#----------------------------------------------------------------------
51
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    25
# Linear Interpolation
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    26
#----------------------------------------------------------------------
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    27
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    28
sub interp($$$)
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    29
{
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    30
	my($x1,$x2,$frac) = @_;
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    31
	return $x1 + $frac * ($x2-$x1);
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    32
}
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    33
14ce2387de5e improved libSBE.pl
Andreas Thurnherr <ant@ldeo.columbia.edu>
parents: 36
diff changeset
    34
#----------------------------------------------------------------------
36
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    35
# Buoyancy-Freuquency Squared
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    36
#	- based on signed buoyancy frequency => propagate sign
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    37
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    38
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    39
{ my(@fc);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    40
	sub Nsq(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    41
	{
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    42
		my($N) = &antsFunUsage(1,'.','[(signed) buoyancy frequency]',\@fc,'N',@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    43
		return ($N < 0) ? -($N**2) : $N**2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    44
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    45
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    46
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 20
diff changeset
    47
#----------------------------------------------------------------------
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
    48
# gaussians/normal distribution
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
    49
#----------------------------------------------------------------------
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
sub gauss(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
	my($x,$peak,$mean,$efs) = &antsFunUsage(4,"ffff","x, peak, mean, e-folding scale",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
	return $peak * exp( -(($x-$mean) / $efs)**2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
sub normal(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
	my($x,$area,$mean,$sigma) = &antsFunUsage(4,"ffff","x, area, mean, stddev",@_);
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
    60
	my($sqrt2pi) = 2.506628274631;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
    61
	return $area/($sqrt2pi*$sigma) * exp(-((($x-$mean) / $sigma)**2)/2);
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
# &f(lat)			calculate coriolis param
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
sub f(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
	my($lat) = &antsFunUsage(1,"f","lat",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
	my($Omega) = 7.292e-5;								# Gill (1982)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
	return 2 * $Omega * sin(rad($lat));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
# &sgn(v)			return -1/0/+1
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
sub sgn(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
	my($val) = &antsFunUsage(1,"f","val",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
	return 0 if ($val == 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
	return ($val < 0) ? -1 : 1;
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
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
# rest of library cooked up from the diverse special function routines of NR
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
# Chapter 6. No attempt to clean up the code has been made.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
# 6.1 Gamma Function et al
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
sub gammln(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
	my($xx) = &antsFunUsage(1,"f","xx",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
	my($x,$y,$tmp,$ser);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
	my(@cof) = (76.18009172947146, 	   -86.50532032941677,
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
				24.01409824083091,     -1.231739572450155,
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
				0.1208650973866179e-2, -0.5395239384953e-5);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
	my($j);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
	$x    = $xx;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
	$y    = $x;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
	$tmp  = $x + 5.5;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
	$tmp -= ($x+0.5) * log($tmp);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
	$ser  = 1.000000000190015;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
	for ($j=0; $j<=5; $j++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
		$ser += $cof[$j] / ++$y;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   112
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   113
	return -$tmp + log(2.5066282746310005*$ser/$x);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   114
}
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
# 6.2. Incomplete Gamma Function, Error Function et al
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
{ my($ITMAX)=100; my($EPS)=3.0e-7;						# static vars
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   121
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   122
sub gser(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   123
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   124
	my($a,$x,$glnR) =  &antsFunUsage(-2,"ff","a,x[,ref to gln]",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   125
	my($gln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   126
	my($n);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   127
	my($sum,$del,$ap);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   128
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   129
	$gln = &gammln($a);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   130
	$$glnR = $gln if (defined($glnR));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   131
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   132
	return 0 if ($x == 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   133
	croak("$0 (libspecfuns.pl): x<0 ($x) in &gser()\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   134
		if ($x < 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   135
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   136
	$ap  = $a;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   137
	$sum = 1 / $a;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   138
	$del = $sum;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   139
	for ($n=1; $n<=$ITMAX; $n++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   140
		++$ap;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   141
		$del *= $x/$ap;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   142
		$sum += $del;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   143
		return $sum * exp(-$x+$a*log($x)-$gln)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   144
			if (abs($del) < abs($sum)*$EPS);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   145
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   146
	croak("$0 (libspecfuns.pl): a ($a) too large, " .
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   147
		"ITMAX ($ITMAX) too small in &gser()\n");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   148
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   149
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   150
} # end of static scope
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   151
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   152
{ my($ITMAX)=100; my($EPS)=3.0e-7; my($FPMIN)=1.0e-30;	# static
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   153
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   154
sub gcf(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   155
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   156
	my($a,$x,$glnR) =  &antsFunUsage(-2,"ff","a,x[,ref to gln]",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   157
	my($gln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   158
	my($i);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   159
	my($an,$b,$c,$d,$del,$h);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   160
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   161
	$gln = &gammln($a);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   162
	$$glnR = $gln if (defined($glnR));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   163
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   164
	$b = $x + 1 - $a;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   165
	croak("$0 (libspecfuns.pl): illegal params (a = x + 1) in &gcf()\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   166
		unless ($b);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   167
	$c = 1 / $FPMIN;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   168
	$d = 1 / $b;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   169
	$h = $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   170
	for ($i=1; $i<=$ITMAX; $i++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   171
		$an = -$i * ($i - $a);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   172
		$b += 2.0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   173
		$d  = $an * $d + $b;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   174
		$d  = $FPMIN if (abs($d) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   175
		$c  = $b + $an/$c;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   176
		$c  = $FPMIN if (abs($c) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   177
		$d  = 1 / $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   178
		$del= $d * $c;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   179
		$h *= $del;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   180
		last if (abs($del-1) < $EPS);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   181
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   182
	croak("$0 (libspecfuns.pl): a ($a) too large," .
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   183
		" ITMAX ($ITMAX) too small in &gcf()\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   184
		if ($i > $ITMAX);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   185
	return exp(-$x + $a*log($x) - $gln) * $h;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   186
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   187
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   188
} # end of static scope
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   189
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   190
sub gammq(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   191
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   192
	my($a,$x) = &antsFunUsage(2,"ff","a,x",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   193
	croak("$0 (libspecfuns.pl): Invalid arguments in &gammq()\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   194
		if ($x < 0 || $a <= 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   195
	return ($x < ($a+1)) ?
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   196
		   1 - &gser($a,$x) :
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   197
		   &gcf($a,$x);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   198
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   199
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   200
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   201
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   202
sub erfcc(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   203
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   204
	my($x) = &antsFunUsage(1,"f","x",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   205
	my($t,$z,$ans);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   206
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   207
	$z = abs($x);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   208
	$t = 1/(1+0.5*$z);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   209
	$ans = $t*exp(-$z*$z-1.26551223+$t*(1.00002368+$t*(0.37409196+$t*(0.09678418+
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   210
		   $t*(-0.18628806+$t*(0.27886807+$t*(-1.13520398+$t*(1.48851587+
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   211
		   $t*(-0.82215223+$t*0.17087277)))))))));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   212
	return $x >= 0 ? $ans : 2.0-$ans;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   213
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   214
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   215
{ my($warned) = 0; # static
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   216
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   217
sub erf(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   218
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   219
	my($x) = &antsFunUsage(1,"f","x",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   220
	&antsInfo("(libspecfuns.pl) WARNING: using approximate erf()"),$warned=1
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   221
		unless ($warned);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   222
	return 1-&erfcc($x);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   223
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   224
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   225
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   226
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   227
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   228
# 6.3. Incomplete Beta Function et al
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   229
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   230
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   231
sub betai(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   232
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   233
	my($a,$b,$x) = &antsFunUsage(3,"fff","a,b,x",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   234
	my($bt);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   235
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   236
	croak("$0 (liberrf.pl): x (=$x) out of range in betai()\n")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   237
		if ($x < 0 || $x > 1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   238
	if ($x == 0 || $x == 1) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   239
		$bt = 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   240
	} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   241
		$bt = exp(gammln($a+$b)-gammln($a)-gammln($b)+$a*log($x)+$b*log(1-$x));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   242
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   243
	if ($x < ($a+1)/($a+$b+2)) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   244
		return $bt * betacf($a,$b,$x) / $a;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   245
	} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   246
		return 1 - $bt*betacf($b,$a,1-$x) / $b;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   247
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   248
}
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
{ # static scope
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   253
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   254
	my($MAXIT) = 100;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   255
	my($EPS)   = 3.0e-7;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   256
	my($FPMIN) = 1.0e-30;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   257
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   258
sub betacf(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   259
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   260
	my($a,$b,$x) = &antsFunUsage(3,"fff","a,b,x",@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   261
	my($m,$m2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   262
	my($aa,$c,$d,$del,$h,$qab,$qam,$qap);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   263
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   264
	$qab = $a + $b;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   265
	$qap = $a + 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   266
	$qam = $a - 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   267
	$c   = 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   268
	$d   = 1 - $qab*$x/$qap;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   269
	$d   = $FPMIN if (abs($d) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   270
	$d   = 1 / $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   271
	$h	 = $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   272
	for ($m=1; $m<=$MAXIT; $m++) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   273
		$m2 = 2 * $m;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   274
		$aa = $m*($b-$m)*$x / (($qam+$m2)*($a+$m2));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   275
		$d  = 1 + $aa*$d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   276
		$d  = $FPMIN if (abs($d) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   277
		$c	= 1 + $aa/$c;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   278
		$c  = $FPMIN if (abs($c) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   279
		$d  = 1 / $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   280
		$h *= $d * $c;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   281
		$aa = -($a+$m)*($qab+$m)*$x / (($a+$m2)*($qap+$m2));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   282
		$d	= 1 + $aa*$d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   283
		$d  = $FPMIN if (abs($d) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   284
		$c  = 1 + $aa/$c;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   285
		$c  = $FPMIN if (abs($c) < $FPMIN);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   286
		$d	= 1 / $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   287
		$del= $d * $c;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   288
		$h *= $del;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   289
		last if (abs($del-1) < $EPS);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   290
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   291
	croak("$0 (liberrf.pl): a or b too big, or MAXIT too small in betacf")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   292
		if ($m > $MAXIT);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   293
	return $h;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   294
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   295
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   296
} # end of static scope
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   297
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   298
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   299
# normalized cardinal sine as used, e.g., in JAOT/polzin02
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   300
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   301
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   302
sub sinc($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   303
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   304
	my($piX) = 3.14159265358979 * $_[0];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   305
	return $piX==0 ? 1 : sin($piX)/$piX;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   306
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   307
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   308
#----------------------------------------------------------------------
3
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   309
# inverse hyperbolic cosine; mathworld
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   310
#	- requires argument >= 1
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   311
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   312
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   313
sub acosh($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   314
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   315
	return log($_[0] + sqrt($_[0]**2-1));
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   316
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   317
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   318
#----------------------------------------------------------------------
20
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   319
# Gaussian random numbers
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   320
#	- optional argument is seed
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   321
#	- http://www.design.caltech.edu/erik/Misc/Gaussian.html
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   322
#	- algorithm generates 2 random numbers
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   323
#	- validated with plot '<count -o samp 1-100000 | list -Lfuns -c x=gaussRand() | Hist -cs 0.05 x',100000.0*0.05/sqrt(2*3.14159265358979)*exp(-x**2/2) wi li
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   324
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   325
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   326
{ my($y2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   327
  my($srand_called);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   328
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   329
sub gaussRand(@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   330
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   331
	if (@_ && !$srand_called) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   332
		srand(@_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   333
		$srand_called = 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   334
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   335
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   336
	if (defined($y2)) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   337
		my($temp) = $y2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   338
		undef($y2);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   339
		return $temp;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   340
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   341
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   342
	my($x1,$x2,$w);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   343
	do {
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   344
		$x1 = 2 * rand() - 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   345
		$x2 = 2 * rand() - 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   346
		$w = $x1**2 + $x2**2;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   347
	} while ($w >= 1);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   348
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   349
	$w = sqrt((-2 * log($w)) / $w);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   350
	$y2 = $x2 * $w;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   351
	return $x1 * $w;
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   352
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   353
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   354
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   355
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 3
diff changeset
   356
#----------------------------------------------------------------------
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   357
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   358
1;