changeset 14598:0d37fda09415

Allow monotonically decending inputs to bicubic (). bicubic.m: Permit the original inputs to be monotonically decending. Slight improvments to coding style. Add test. (Bug # 36351).
author Ben Abbott <bpabbott@mac.com>
date Thu, 03 May 2012 18:34:39 -0400
parents 11a9d448fdc3
children de72463862c4
files scripts/general/bicubic.m
diffstat 1 files changed, 44 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/general/bicubic.m	Thu May 03 12:15:21 2012 -0400
+++ b/scripts/general/bicubic.m	Thu May 03 18:34:39 2012 -0400
@@ -50,9 +50,9 @@
 
   if (isa (x, "single") || isa (y, "single") || isa (z, "single")
       || isa (xi, "single") || isa (yi, "single"))
-    myeps = eps("single");
+    myeps = eps ("single");
   else
-    myeps = eps;
+    myeps = eps ();
   endif
 
   if (nargin <= 2)
@@ -65,8 +65,8 @@
     z = x;
     x = [];
     [rz, cz] = size (z);
-    s = linspace (1, cz, (cz-1)*pow2(n)+1);
-    t = linspace (1, rz, (rz-1)*pow2(n)+1);
+    s = linspace (1, cz, (cz-1) * pow2 (n) + 1);
+    t = linspace (1, rz, (rz-1) * pow2 (n) + 1);
   elseif (nargin == 3)
     if (! isvector (x) || ! isvector (y))
       error ("bicubic: XI and YI must be vector");
@@ -88,6 +88,23 @@
       error ("bicubic: X, Y and Z must be equal size matrices of same size");
     endif
 
+    if (all (diff (x) < 0))
+      flipx = true;
+      x = fliplr (x);
+    elseif (all (diff (x) > 0))
+      flipx = false;
+    else
+      error ("bicubic:nonmonotonic", "bicubic: X values must be monotonic")
+    endif
+    if (all (diff (y) < 0))
+      flipy = true;
+      y = flipud (y);
+    elseif (all (diff (y) > 0))
+      flipy = false;
+    else
+      error ("bicubic:nonmonotonic", "bicubic: Y values must be monotonic")
+    endif
+
     ## Mark values outside the lookup table.
     xfirst_ind = find (xi < x(1));
     xlast_ind  = find (xi > x(cz));
@@ -99,9 +116,8 @@
     yi(yfirst_ind) = y(1);
     yi(ylast_ind) = y(rz);
 
-
     x = reshape (x, 1, cz);
-    x(cz) *= 1 + sign (x(cz))*myeps;
+    x(cz) *= 1 + sign (x(cz)) * myeps;
     if (x(cz) == 0)
       x(cz) = myeps;
     endif;
@@ -111,7 +127,7 @@
     xidx = o(find (i > cz));
 
     y = reshape (y, rz, 1);
-    y(rz) *= 1 + sign (y(rz))*myeps;
+    y(rz) *= 1 + sign (y(rz)) * myeps;
     if (y(rz) == 0)
       y(rz) = myeps;
     endif;
@@ -121,8 +137,15 @@
     yidx = o([find(i > rz)]);
 
     ## Set s and t used follow codes.
-    s = xidx + ((xi .- x(xidx))./(x(xidx+1) .- x(xidx)));
-    t = yidx + ((yi - y(yidx))./(y(yidx+1) - y(yidx)));
+    s = xidx + ((xi .- x(xidx)) ./ (x(xidx+1) .- x(xidx)));
+    t = yidx + ((yi  - y(yidx)) ./ (y(yidx+1)  - y(yidx)));
+
+    if (flipx)
+      s = fliplr (s);
+    endif
+    if (flipy)
+      t = flipud (t);
+    endif
   else
     print_usage ();
   endif
@@ -198,7 +221,6 @@
 
 endfunction
 
-
 %!demo
 %! clf;
 %! colormap ("default");
@@ -211,3 +233,15 @@
 %! [x,y] = meshgrid (x,y);
 %! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
 
+%!test
+%! x = linspace (1, -1, 10);
+%! [xx, yy] = meshgrid (x);
+%! z = cos (6 * xx) + sin (6 * yy);
+%! x = linspace (1, -1, 30);
+%! [xx2, yy2] = meshgrid (x);
+%! z1 = interp2 (xx, yy, z, xx2, yy2, "cubic");
+%! z2 = interp2 (fliplr(xx), flipud(yy), fliplr(flipud(z)),
+%!               fliplr(xx2), flipud(yy2), "cubic");
+%! z2 = fliplr (flipud (z2));
+%! assert (z1, z2, 100 * eps ())
+