Mercurial > forge
comparison main/general/interp2.m @ 0:6b33357c7561 octave-forge
Initial revision
author | pkienzle |
---|---|
date | Wed, 10 Oct 2001 19:54:49 +0000 |
parents | |
children | 3165e038dba4 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:6b33357c7561 |
---|---|
1 ## Copyright (C) 2000 Kai Habel | |
2 ## | |
3 ## This program is free software; you can redistribute it and/or modify | |
4 ## it under the terms of the GNU General Public License as published by | |
5 ## the Free Software Foundation; either version 2 of the License, or | |
6 ## (at your option) any later version. | |
7 ## | |
8 ## This program is distributed in the hope that it will be useful, | |
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 ## GNU General Public License for more details. | |
12 ## | |
13 ## You should have received a copy of the GNU General Public License | |
14 ## along with this program; if not, write to the Free Software | |
15 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
16 | |
17 ## -*- texinfo -*- | |
18 ## @deftypefn {Function File} {@var{zi}=} interp2 (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}) | |
19 ## @deftypefnx {Function File} {@var{zi}=} interp2 (@var{Z}, @var{xi}, @var{yi}) | |
20 ## @deftypefnx {Function File} {@var{zi}=} interp2 (@var{Z}, @var{n}) | |
21 ## @deftypefnx {Function File} {@var{zi}=} interp2 (... , '@var{method}') | |
22 ## Two-dimensional interpolation. @var{X},@var{Y} and @var{Z} describe a | |
23 ## surface function. If @var{X} and @var{Y} are vectors their length | |
24 ## must correspondent to the size of @var{Z}. If they are matrices they | |
25 ## must have the 'meshgrid' format. | |
26 ## | |
27 ## ZI = interp2 (X, Y, Z, XI, YI, ...) returns a matrix corresponding | |
28 ## to the points described by the matrices @var{XI}, @var{YI}. | |
29 ## | |
30 ## If the last argument is a string, the interpolation method can | |
31 ## be specified. At the moment only 'linear' and 'nearest' methods | |
32 ## are provided. If it is omitted 'linear' interpolation is | |
33 ## assumed. | |
34 ## | |
35 ## ZI = interp2 (Z, XI, YI) assumes X = 1:rows(Z) and Y = 1:columns(Z) | |
36 ## | |
37 ## ZI = interp2 (Z, n) interleaves the Matrix Z n-times. If n is ommited | |
38 ## n = 1 is assumed | |
39 ## | |
40 ## @seealso{interp1} | |
41 ## @end deftypefn | |
42 | |
43 ## Author: Kai Habel <kai.habel@gmx.de> | |
44 | |
45 function ZI = interp2 (X, Y, Z, XI, YI, method) | |
46 | |
47 if (nargin > 6 || nargin == 0) | |
48 usage ("interp2 (X, Y, Z, XI, YI, method)"); | |
49 endif | |
50 | |
51 if (nargin > 4) | |
52 if (is_vector (X) && is_vector (Y)) | |
53 [rz, cz] = size (Z); | |
54 if (rz != length (Y) || cz != length (X)) | |
55 error ("length of X and Y must match the size of Z"); | |
56 endif | |
57 [X, Y] = meshgrid (X, Y); | |
58 elseif !( (size (X) == size (Y)) && (size (X) == size (Z)) ) | |
59 error ("X,Y and Z must be matrices of same size"); | |
60 endif | |
61 endif | |
62 | |
63 if (((nargin == 4) || (nargin == 3)) && !isstr (Z)) | |
64 | |
65 if (nargin == 4) | |
66 if (isstr (XI)) | |
67 method = XI; | |
68 else | |
69 usage("interp2 (z,xi,yi,'format'"); | |
70 endif | |
71 endif | |
72 XI = Y; | |
73 YI = Z; | |
74 Z = X; | |
75 [X, Y] = meshgrid(1:columns(Z), 1:rows(Z)); | |
76 else | |
77 if (nargin == 1) | |
78 n = 1; | |
79 elseif (nargin == 2) | |
80 if (isstr (Y)) | |
81 method = Y; | |
82 n = 1; | |
83 elseif (is_scalar (Y)) | |
84 n = Y; | |
85 endif | |
86 else | |
87 n = Y; | |
88 if (isstr (Z)) | |
89 method = Z; | |
90 endif | |
91 endif | |
92 Z = X; | |
93 [zr, zc] = size (Z); | |
94 [X, Y] = meshgrid (1:zc, 1:zr); | |
95 xi = linspace (1, zc, pow2 (n) * (zc - 1) + 1); | |
96 yi = linspace (1, zr, pow2 (n) * (zr - 1) + 1); | |
97 [XI, YI] = meshgrid (xi, yi); | |
98 endif | |
99 | |
100 if (! exist ("method")) | |
101 method = "linear"; | |
102 endif | |
103 | |
104 xtable = X(1, :); | |
105 ytable = Y(:, 1); | |
106 | |
107 if (is_vector (XI) && is_vector (YI)) | |
108 [XI, YI] = meshgrid (XI, YI); | |
109 elseif (! (size (XI) == size (YI))) | |
110 error ("XI and YI must be matrices of same size"); | |
111 endif | |
112 | |
113 ytlen = length (ytable); | |
114 xtlen = length (xtable); | |
115 | |
116 ## get x index of values in XI | |
117 xtable(xtlen) *= (1 + eps); | |
118 xtable(xtlen) > XI(1, :); | |
119 [m, n] = sort ([xtable(:); XI(1, :)']); | |
120 o = cumsum (n <= xtlen); | |
121 xidx = o([find (n > xtlen)])'; | |
122 | |
123 ## get y index of values in YI | |
124 ytable(ytlen) *= (1 + eps); | |
125 [m, n]=sort ([ytable(:); YI(:, 1)]); | |
126 o = cumsum (n <= ytlen); | |
127 yidx = o([find (n > ytlen)]); | |
128 | |
129 [zr, zc] = size (Z); | |
130 | |
131 ## mark values outside the lookup table | |
132 xfirst_val = find (XI(1,:) < xtable(1)); | |
133 xlast_val = find (XI(1,:) > xtable(xtlen)); | |
134 yfirst_val = find (YI(:,1) < ytable(1)); | |
135 ylast_val = find (YI(:,1) > ytable(ytlen)); | |
136 | |
137 ## set value outside the table preliminary to min max index | |
138 yidx(yfirst_val) = 1; | |
139 xidx(xfirst_val) = 1; | |
140 yidx(ylast_val) = zr - 1; | |
141 xidx(xlast_val) = zc - 1; | |
142 | |
143 if strcmp (method, "linear") | |
144 ## each quad satisfies the equation z(x,y)=a+b*x+c*y+d*xy | |
145 ## | |
146 ## a-b | |
147 ## | | | |
148 ## c-d | |
149 a = Z(1:zr - 1, 1:zc - 1); | |
150 b = Z(1:zr - 1, 2:zc) - a; | |
151 c = Z(2:zr, 1:zc - 1) - a; | |
152 d = Z(2:zr, 2:zc) - a - b - c; | |
153 | |
154 ## scale XI,YI values to a 1-spaced grid | |
155 Xsc = (XI .- X(yidx, xidx)) ./ (X(yidx, xidx + 1) - X(yidx, xidx)); | |
156 Ysc = (YI .- Y(yidx, xidx)) ./ (Y(yidx + 1, xidx) - Y(yidx, xidx)); | |
157 ## apply plane equation | |
158 ZI = a(yidx, xidx) .+ b(yidx, xidx) .* Xsc \ | |
159 .+ c(yidx, xidx) .* Ysc .+ d(yidx, xidx) .* Xsc .* Ysc; | |
160 elseif strcmp (method, "nearest") | |
161 i = XI(1, :) - xtable(xidx) > xtable(xidx + 1) - XI(1, :); | |
162 j = YI(:, 1) - ytable(yidx) > ytable(yidx + 1) - YI(:, 1); | |
163 ZI = Z(yidx + j, xidx + i); | |
164 else | |
165 error ("interpolation method not (yet) supported"); | |
166 endif | |
167 | |
168 ## set points outside the table to NaN | |
169 if (! (isempty (xfirst_val) && isempty (xlast_val))) | |
170 ZI(:, [xfirst_val, xlast_val]) = NaN; | |
171 endif | |
172 if (! (isempty (yfirst_val) && isempty (ylast_val))) | |
173 ZI([yfirst_val; ylast_val], :) = NaN; | |
174 endif | |
175 endfunction | |
176 | |
177 %!demo | |
178 %! A=[13,-1,12;5,4,3;1,6,2]; | |
179 %! x=[0,1,4]; y=[10,11,12]; | |
180 %! xi=linspace(min(x),max(x),17); | |
181 %! yi=linspace(min(y),max(y),26); | |
182 %! mesh(xi,yi,interp2(x,y,A,xi,yi,'linear')); | |
183 %! [x,y] = meshgrid(x,y); gset nohidden3d; | |
184 %! hold on; plot3(x(:),y(:),A(:),"b*"); hold off; | |
185 | |
186 %!demo | |
187 %! A=[13,-1,12;5,4,3;1,6,2]; | |
188 %! x=[0,1,4]; y=[10,11,12]; | |
189 %! xi=linspace(min(x),max(x),17); | |
190 %! yi=linspace(min(y),max(y),26); | |
191 %! mesh(xi,yi,interp2(x,y,A,xi,yi,'nearest')); | |
192 %! [x,y] = meshgrid(x,y); gset nohidden3d; | |
193 %! hold on; plot3(x(:),y(:),A(:),"b*"); hold off; | |
194 | |
195 %!#demo | |
196 %! A=[13,-1,12;5,4,3;1,6,2]; | |
197 %! x=[0,1,2]; y=[10,11,12]; | |
198 %! xi=linspace(min(x),max(x),17); | |
199 %! yi=linspace(min(y),max(y),26); | |
200 %! mesh(xi,yi,interp2(x,y,A,xi,yi,'cubic')); | |
201 %! [x,y] = meshgrid(x,y); gset nohidden3d; | |
202 %! hold on; plot3(x(:),y(:),A(:),"b*"); hold off; |