39
|
1 |
#======================================================================
|
|
2 |
# . I N T E R P . P O L Y
|
|
3 |
# doc: Thu Nov 23 21:30:25 2000
|
|
4 |
# dlm: Tue Aug 5 14:20:19 2008
|
|
5 |
# (c) 2000 A.M. Thurnherr
|
|
6 |
# uE-Info: 58 0 NIL 0 0 72 10 2 4 NIL ofnI
|
|
7 |
#======================================================================
|
|
8 |
|
|
9 |
# polynomial interpolation
|
|
10 |
|
|
11 |
# HISTORY:
|
|
12 |
# Nov 23, 2000: - created
|
|
13 |
# Nov 24, 2000: - added -c)enter x-val in window
|
|
14 |
# Dec 13, 2002: - replaced -n by -o
|
|
15 |
# Oct 22, 2003: - changed -e to -r (conflicts with -e option of [resample])
|
|
16 |
# Jul 28, 2006: - removed debugging code
|
|
17 |
# - added xf to ISInit() args
|
|
18 |
# - BUG: sufficient-input data test was buggy
|
|
19 |
# Aug 22, 2006: - adapted to work with [match]
|
|
20 |
# Sep 11, 2006: - BUG: sufficient-input ermesg was wrong
|
|
21 |
# Aug 5, 2008: - added idr param to IS_init()
|
|
22 |
|
|
23 |
# see [.interp.linear] for documentation of interface
|
|
24 |
|
|
25 |
# NOTES:
|
|
26 |
# - $opt_o <poly order> is required
|
|
27 |
# - $opt_r is used to return the error estimates instead of the
|
|
28 |
# interpolated values
|
|
29 |
# - -o 0 is almost like using -s subsample, the only difference
|
|
30 |
# being that subsample returns the real x values while -o 0
|
|
31 |
# returns the subsampled x values
|
|
32 |
# - on -c the window for each interpolation estimate is centered
|
|
33 |
# around the interpolated x value; this implies window-sliding
|
|
34 |
# between tabulated x values resulting in functional disconti-
|
|
35 |
# nuities
|
|
36 |
|
|
37 |
require "$ANTS/polint.pl";
|
|
38 |
|
|
39 |
$IS_opts = "co:r";
|
|
40 |
$IS_optsUsage = "[e-r)ror estimates] [-c)enter x-val] -o <poly order>";
|
|
41 |
|
|
42 |
sub IS_usage()
|
|
43 |
{
|
|
44 |
die("$0 (.interp.poly): ERROR! -o required\n")
|
|
45 |
unless (defined($opt_o) && $opt_o >= 0);
|
|
46 |
&antsInfo("WARNING: -c generates discontinuous function")
|
|
47 |
if ($opt_c);
|
|
48 |
&antsInfo("WARNING: high-order polynomial interpolation deprecated")
|
|
49 |
if ($opt_o > 5);
|
|
50 |
&antsInfo("order-1 polynomial; -s linear is more efficient")
|
|
51 |
if ($opt_o == 1);
|
|
52 |
&antsInfo("giving error estimates") if ($opt_r);
|
|
53 |
}
|
|
54 |
|
|
55 |
sub IS_init($$$$)
|
|
56 |
{
|
|
57 |
my($bR,$idR,$f,$xf) = @_;
|
|
58 |
die(sprintf("$0 (.interp.poly): ERROR! " .
|
|
59 |
"not enough data points (%d) for order-$opt_o poly\n",
|
|
60 |
$#{$bR}+1))
|
|
61 |
if ($opt_o > $#{$bR});
|
|
62 |
}
|
|
63 |
|
|
64 |
sub findWindow($$$$$) # find window of size n=opt_o+1
|
|
65 |
{
|
|
66 |
my($bR,$f,$v,$i,$n) = @_;
|
|
67 |
my($cn); # current win size
|
|
68 |
|
|
69 |
return ($bR->[$i+1][$f] - $v < $v - $bR->[$i][$f]) ? $i+1 : $i
|
|
70 |
if ($n == 1); # nearest neighbor
|
|
71 |
|
|
72 |
if ($opt_c) { # center window around x value
|
|
73 |
for ($cn=2; $cn<$n; $cn++) { # grow window
|
|
74 |
$i-- if (($i>0 && $bR->[$i+$cn-1][$f] - $v >= $v - $bR->[$i][$f]) ||
|
|
75 |
($i+$cn-1 == $#{$bR}));
|
|
76 |
}
|
|
77 |
} else {
|
|
78 |
$i -= int(($n-1)/2); # ideally
|
|
79 |
$i = 0 if ($i < 0); # off leftmost column
|
|
80 |
$i = $#{$bR}+1 - $n if ($i+$n > $#{$bR}+1);# off rightmost column
|
|
81 |
}
|
|
82 |
|
|
83 |
return $i;
|
|
84 |
}
|
|
85 |
|
|
86 |
sub IS_interpolate($$$$$$)
|
|
87 |
{
|
|
88 |
my($bR,$idR,$xf,$xv,$xi,$f) = @_;
|
|
89 |
return $xv if ($xf == $f);
|
|
90 |
|
|
91 |
$xi = &findWindow($bR,$xf,$xv,$xi,$opt_o+1);
|
|
92 |
my($y,$dy) = &polint($bR,$xf,$xv,$xi,$opt_o+1,$f);
|
|
93 |
return $opt_r ? $dy : $y;
|
|
94 |
}
|