diff scripts/general/interp2.m @ 6702:b2391d403ed2

[project @ 2007-06-12 21:39:26 by dbateman]
author dbateman
date Tue, 12 Jun 2007 21:39:27 +0000
parents 2110cc251779
children ebf96cc00ee9
line wrap: on
line diff
--- a/scripts/general/interp2.m	Tue Jun 12 21:25:51 2007 +0000
+++ b/scripts/general/interp2.m	Tue Jun 12 21:39:27 2007 +0000
@@ -62,7 +62,7 @@
 ## Cubic interpolation from four nearest neighbors.
 ## @item 'spline'
 ## Cubic spline interpolation--smooth first and second derivatives
-## throughout the curve (not implemented yet).
+## throughout the curve.
 ## @end table
 ##
 ## If a scalar value @var{extrapval} is defined as the final value, then
@@ -161,75 +161,102 @@
     error ("interp2 expected numeric XI, YI"); 
   endif
 
-  ## If X and Y vectors produce a grid from them
-  if (isvector (X) && isvector (Y))
-    [X, Y] = meshgrid (X, Y);
-  elseif (! size_equal (X, Y))
-    error ("X and Y must be matrices of same size");
-  endif
-  if (! size_equal (X, Z))
-    error ("X and Y size must match Z dimensions");
-  endif
+
+  if (strcmp (method, "linear") || strcmp (method, "nearest"))
+
+    ## If X and Y vectors produce a grid from them
+    if (isvector (X) && isvector (Y))
+      [X, Y] = meshgrid (X, Y);
+    elseif (! size_equal (X, Y))
+      error ("X and Y must be matrices of same size");
+    endif
+    if (! size_equal (X, Z))
+      error ("X and Y size must match Z dimensions");
+    endif
+
+    ## If Xi and Yi are vectors of different orientation build a grid
+    if ((rows (XI) == 1 && columns (YI) == 1)
+	|| (columns (XI) == 1 && rows (YI) == 1))
+      [XI, YI] = meshgrid (XI, YI);
+    elseif (! size_equal (XI, YI))
+      error ("XI and YI must be matrices of same size");
+    endif
 
-  ## If Xi and Yi are vectors of different orientation build a grid
-  if ((rows (XI) == 1 && columns (YI) == 1)
-      || (columns (XI) == 1 && rows (YI) == 1))
-    [XI, YI] = meshgrid (XI, YI);
-  elseif (! size_equal (XI, YI))
-    error ("XI and YI must be matrices of same size");
-  endif
+    shape = size (XI);
+    XI = reshape (XI, 1, prod (shape));
+    YI = reshape (YI, 1, prod (shape));
+
+    xidx = lookup (X(1, 2:end-1), XI) + 1;
+    yidx = lookup (Y(2:end-1, 1), YI) + 1;
 
-  shape = size (XI);
-  XI = reshape (XI, 1, prod (shape));
-  YI = reshape (YI, 1, prod (shape));
+    if (strcmp (method, "linear"))
+      ## each quad satisfies the equation z(x,y)=a+b*x+c*y+d*xy
+      ##
+      ## a-b
+      ## | |
+      ## c-d
+      a = Z(1:(zr - 1), 1:(zc - 1));
+      b = Z(1:(zr - 1), 2:zc) - a;
+      c = Z(2:zr, 1:(zc - 1)) - a;
+      d = Z(2:zr, 2:zc) - a - b - c;
 
-  xidx = lookup (X(1, 2:end-1), XI) + 1;
-  yidx = lookup (Y(2:end-1, 1), YI) + 1;
+      idx = sub2ind (size (a), yidx, xidx);
+
+      ## scale XI, YI values to a 1-spaced grid
+      Xsc = (XI - X(1, xidx)) ./ (X(1, xidx + 1) - X(1, xidx));
+      Ysc = (YI - Y(yidx, 1)') ./ (Y(yidx + 1, 1) - Y(yidx, 1))';
+
+      ## apply plane equation
+      ZI = a(idx) + b(idx).*Xsc + c(idx).*Ysc + d(idx).*Xsc.*Ysc;
 
-  if (strcmp (method, "linear"))
-    ## each quad satisfies the equation z(x,y)=a+b*x+c*y+d*xy
-    ##
-    ## a-b
-    ## | |
-    ## c-d
-    a = Z(1:(zr - 1), 1:(zc - 1));
-    b = Z(1:(zr - 1), 2:zc) - a;
-    c = Z(2:zr, 1:(zc - 1)) - a;
-    d = Z(2:zr, 2:zc) - a - b - c;
+    elseif (strcmp (method, "nearest"))
+      xtable = X(1, :);
+      ytable = Y(:, 1)';
+      ii = (XI - xtable(xidx) > xtable(xidx + 1) - XI);
+      jj = (YI - ytable(yidx) > ytable(yidx + 1) - YI);
+      idx = sub2ind (size (Z), yidx+jj, xidx+ii);
+      ZI = Z(idx);
+    endif
 
-    idx = sub2ind (size (a), yidx, xidx);
-
-    ## scale XI, YI values to a 1-spaced grid
-    Xsc = (XI - X(1, xidx)) ./ (X(1, xidx + 1) - X(1, xidx));
-    Ysc = (YI - Y(yidx, 1)') ./ (Y(yidx + 1, 1) - Y(yidx, 1))';
-
-    ## apply plane equation
-    ZI = a(idx) + b(idx).*Xsc + c(idx).*Ysc + d(idx).*Xsc.*Ysc;
+    ## set points outside the table to NaN
+    ZI (XI < X(1,1) | XI > X(1,end) | YI < Y(1,1) | YI > Y(end,1)) = extrapval;
+    ZI = reshape (ZI, shape);
+  else
 
-  elseif (strcmp (method, "nearest"))
-    xtable = X(1, :);
-    ytable = Y(:, 1)';
-    ii = (XI - xtable(xidx) > xtable(xidx + 1) - XI);
-    jj = (YI - ytable(yidx) > ytable(yidx + 1) - YI);
-    idx = sub2ind (size (Z), yidx+jj, xidx+ii);
-    ZI = Z(idx);
-
-  elseif (strcmp (method, "cubic"))
-    ## FIXME bicubic doesn't handle arbitrary XI, YI
-    ZI = bicubic (X, Y, Z, XI(1,:), YI(:,1));
+    ## If X and Y vectors produce a grid from them
+    if (isvector (X) && isvector (Y))
+      X = X(:).';
+      Y = Y(:);
+      if (!isequal ([length(X), length(Y)], size(Z)))
+	error ("X and Y size must match Z dimensions");
+      endif
+    elseif (!size_equal (X, Y))
+      error ("X and Y must be matrices of same size");
+      if (! size_equal (X, Z))
+	error ("X and Y size must match Z dimensions");
+      endif
+    endif
 
-  elseif (strcmp (method, "spline"))
-    ## FIXME Implement 2-D (or in fact ND) spline interpolation
-    error ("interp2, spline interpolation not yet implemented");
+    ## If Xi and Yi are vectors of different orientation build a grid
+    if ((rows (XI) == 1 && columns (YI) == 1)
+	|| (columns (XI) == 1 && rows (YI) == 1))
+      ## Do nothing
+    elseif (! size_equal (XI, YI))
+      error ("XI and YI must be matrices of same size");
+    endif
 
-  else
-    error ("interpolation method not recognized");
-  endif
+    ## FIXME bicubic/__splinen__ don't handle arbitrary XI, YI
+    if (strcmp (method, "cubic"))
+      ZI = bicubic (X, Y, Z, XI(1,:), YI(:,1), extrapval);
 
-  ## set points outside the table to NaN
-  ZI (XI < X(1,1) | XI > X(1,end) | YI < Y(1,1) | YI > Y(end,1)) = extrapval;
-  ZI = reshape (ZI, shape);
+    elseif (strcmp (method, "spline"))
+      ZI = __splinen__ ({Y(:,1).', X(1,:)}, Z, {YI(:,1), XI(1,:)}, extrapval, 
+			"spline");
+    else
+      error ("interpolation method not recognized");
+    endif
 
+  endif
 endfunction
 
 %!demo
@@ -250,15 +277,24 @@
 %! [x,y] = meshgrid(x,y); 
 %! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
 
-%!#demo
+%!demo
 %! A=[13,-1,12;5,4,3;1,6,2];
 %! x=[0,1,2]; y=[10,11,12];
 %! xi=linspace(min(x),max(x),17);
-%! yi=linspace(min(y),max(y),26);
+%! yi=linspace(min(y),max(y),26)';
 %! mesh(xi,yi,interp2(x,y,A,xi,yi,'cubic'));
 %! [x,y] = meshgrid(x,y); 
 %! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
 
+%!demo
+%! A=[13,-1,12;5,4,3;1,6,2];
+%! x=[0,1,2]; y=[10,11,12];
+%! xi=linspace(min(x),max(x),17);
+%! yi=linspace(min(y),max(y),26)';
+%! mesh(xi,yi,interp2(x,y,A,xi,yi,'spline'));
+%! [x,y] = meshgrid(x,y); 
+%! hold on; plot3(x(:),y(:),A(:),"b*"); hold off;
+
 %!test % simple test
 %!  x = [1,2,3];
 %!  y = [4,5,6,7];