.nminterp.linear
author Andreas Thurnherr <ant@ldeo.columbia.edu>
Mon, 13 Apr 2020 11:06:22 -0400
changeset 40 c1803ae2540f
parent 39 56bdfe65a697
permissions -rw-r--r--
.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     1
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     2
#                    . N M I N T E R P . L I N E A R 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#                    doc: Wed Nov 22 21:01:09 2000
39
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 30
diff changeset
     4
#                    dlm: Fri Aug 30 13:26:58 2019
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 2000 A.M. Thurnherr
39
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 30
diff changeset
     6
#                    uE-Info: 101 9 NIL 0 0 72 0 2 4 NIL ofnI
30
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
# linear interpolation for [fillgaps]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
# HISTORY:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
#	Apr  6, 2006: - created from [.interp.linear]
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
#	Jul 28, 2006: - added xf to ISInit() args
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
#	Jul 30, 2006: - added max-gap support
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
#	Aug  8, 2008: - documentation
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    16
#	Sep 23, 2011: - added support for %RECNO
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    17
#				  - removed xv from interp() args
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    18
#	Oct 19, 2011: - code did not work for %RECNO and trailing missing vals
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    19
#	Jan 23, 2014: - implemented huge speedup for sparse files
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    20
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
# NOTES:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
#	- in contrast to the [.interp.*] routines, the [.nminterp.*] routines:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
#		1) do not assume that x values increase monotonically
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#		2) can handle nans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    25
#		3) cannot be used with multiple buffers
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
#		4) use %RECNO when xfnr==-1
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
# THE FOLLOWING VARIABLES MUST BE SET GLOBALLY (i.e. during loading)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
#	$ISOpts				string of allowed options
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    33
#	$ISOptsUsage		usage information string for options
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    35
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    36
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    37
$ISOpts = "";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
$ISOptsUsage = "";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
# &ISUsage() 	mangle parameters (options, really)
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
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
sub ISUsage() {}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
# &ISInit(f,xf)				init interpolation of field f
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
#       f					field number
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
#		xf					x field number or -1 for %RECNO
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
#       <ret val>           none
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
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
sub ISInit($$) {}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
# &interpolate(xf,mg,f,lvr,cr)		interpolate field f
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
#		xf							x field or -1 for %RECNO
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
#		mg							max allowed x gap
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
#		f							field number to interpolate
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
#		lvr							last record with valid y val
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
#		cr							current record
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
#		<ret val>					interpolated value
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
# NB:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
#	- handle f == xf
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
#	- return undef if interpolation cannot be carried out
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
#	- x VALUES MAY NOT BE MONOTONIC
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
#
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
{ my(@nvr);		# static: next valid record (per field)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
	sub interpolate($$$$$$)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
	{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
		my($xf,$mg,$f,$lvr,$cr) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
		return $ants_[$cr][$xf] if ($xf == $f);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
		return $ants_[$lvr][$f] 				# edge value is ok
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
			if ($xf>=0 && equal($ants_[$cr][$xf],$ants_[$lvr][$xf])) ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    85
			   ($xf<0 && $cr==$lvr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
		unless ($nvr[$f] > $cr) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
			$nvr[$f] = $cr + 1;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
			while ($nvr[$f] <= $#ants_ && !numberp($ants_[$nvr[$f]][$f])) { $nvr[$f]++; }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
		return undef if ($nvr[$f] > $#ants_);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
		return undef
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
			if ($xf>=0 && abs($ants_[$nvr[$f]][$xf]-$ants_[$lvr][$xf])>$mg);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
		return $ants_[$nvr[$f]][$f] 				# edge value is ok
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
			if ($xf>=0 && equal($ants_[$cr][$xf],$ants_[$nvr[$f]][$xf])) ||
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
			   ($xf<0 && $cr==$nvr[$f]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
	
39
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 30
diff changeset
    99
		if ($xf < 0) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 30
diff changeset
   100
			die("$nvr[$f] - $lvr") unless ($nvr[$f] - $lvr > 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 30
diff changeset
   101
        }
30
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
		my($sc) = ($xf >= 0)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
				? ($ants_[$cr][$xf] - $ants_[$lvr][$xf]) / ($ants_[$nvr[$f]][$xf] - $ants_[$lvr][$xf])
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
				: ($cr - $lvr) / ($nvr[$f] - $lvr);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
		return $ants_[$lvr][$f] + $sc * ($ants_[$nvr[$f]][$f] - $ants_[$lvr][$f]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
} # static scope
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
1;