changeset 21172:5f62b5dae8b1 stable

Fix regression for coordinate transforms on 3-D arrays (partial fix bug #47036). ismatrix changed definitions from 3.8 to 4.0 causing a regression. I replaced these calls with isnumeric. The meaning is not quite the same as ismatrix was previously true for logical and char: but there is little reason to support those here (anyone calling cart2sph on a char almost certainly has a bug!). * cart2pol.m, cart2sph.m, pol2cart.m, sph2cart.m: Replace ismatrix with isnumeric. Rephrase error messages to mention "array" rather than "matrix" and to include variable namse that are in error. Add BIST tests for NDarrays and input validation.
author Colin Macdonald <cbm@m.fsf.org>
date Sun, 31 Jan 2016 21:05:08 -0800
parents 2935d56203a4
children 5ecdcc6320d9
files scripts/general/cart2pol.m scripts/general/cart2sph.m scripts/general/pol2cart.m scripts/general/sph2cart.m
diffstat 4 files changed, 168 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/general/cart2pol.m	Mon Feb 01 22:59:43 2016 -0800
+++ b/scripts/general/cart2pol.m	Sun Jan 31 21:05:08 2016 -0800
@@ -1,4 +1,4 @@
-## Copyright (C) 2000-2015 Kai Habel
+## Copyright (C) 2000-2016 Kai Habel
 ##
 ## This file is part of Octave.
 ##
@@ -49,26 +49,26 @@
   endif
 
   if (nargin == 1)
-    if (ismatrix (x) && (columns (x) == 2 || columns (x) == 3))
-      if (columns (x) == 3)
-        z = x(:,3);
-      endif
-      y = x(:,2);
-      x = x(:,1);
-    else
+    if (! (isnumeric (x) && ismatrix (x)
+           && (columns (x) == 2 || columns (x) == 3)))
       error ("cart2pol: matrix input must have 2 or 3 columns [X, Y (, Z)]");
     endif
+    if (columns (x) == 3)
+      z = x(:,3);
+    endif
+    y = x(:,2);
+    x = x(:,1);
   elseif (nargin == 2)
-    if (! ((ismatrix (x) && ismatrix (y))
+    if (! ((isnumeric (x) && isnumeric (y))
             && (size_equal (x, y) || isscalar (x) || isscalar (y))))
-      error ("cart2pol: arguments must be matrices of same size, or scalar");
+      error ("cart2pol: X, Y must be numeric arrays of the same size, or scalar");
     endif
   elseif (nargin == 3)
-    if (! ((ismatrix (x) && ismatrix (y) && ismatrix (z))
+    if (! ((isnumeric (x) && isnumeric (y) && isnumeric (z))
             && (size_equal (x, y) || isscalar (x) || isscalar (y))
             && (size_equal (x, z) || isscalar (x) || isscalar (z))
             && (size_equal (y, z) || isscalar (y) || isscalar (z))))
-      error ("cart2pol: arguments must be matrices of same size, or scalar");
+      error ("cart2pol: X, Y, Z must be numeric arrays of the same size, or scalar");
     endif
   endif
 
@@ -142,3 +142,41 @@
 %! P = [0, 0, 0; pi/4, sqrt(2), 1; pi/4, 2*sqrt(2), 2];
 %! assert (cart2pol (C), P, sqrt (eps));
 
+%!test
+%! x = zeros (1, 1, 1, 2);
+%! x(1, 1, 1, 2) = sqrt (2);
+%! y = x;
+%! [t, r] = cart2pol (x, y);
+%! T = zeros (1, 1, 1, 2);
+%! T(1, 1, 1, 2) = pi/4;
+%! R = zeros (1, 1, 1, 2);
+%! R(1, 1, 1, 2) = 2;
+%! assert (t, T, eps);
+%! assert (r, R, eps);
+
+%!test
+%! [x, y, Z] = meshgrid ([0, 1], [0, 1], [0, 1]);
+%! [t, r, z] = cart2pol (x, y, Z);
+%! T(:, :, 1) = [0, 0; pi/2, pi/4];
+%! T(:, :, 2) = T(:, :, 1);
+%! R = sqrt (x.^2 + y.^2);
+%! assert (t, T, eps);
+%! assert (r, R, eps);
+%! assert (z, Z);
+
+## Test input validation
+%!error cart2pol ()
+%!error cart2pol (1,2,3,4)
+%!error <matrix input must have 2 or 3 columns> cart2pol ({1,2,3})
+%!error <matrix input must have 2 or 3 columns> cart2pol (ones (3,3,2))
+%!error <matrix input must have 2 or 3 columns> cart2pol ([1])
+%!error <matrix input must have 2 or 3 columns> cart2pol ([1,2,3,4])
+%!error <numeric arrays of the same size> cart2pol ({1,2,3}, [1,2,3])
+%!error <numeric arrays of the same size> cart2pol ([1,2,3], {1,2,3})
+%!error <numeric arrays of the same size> cart2pol (ones (3,3,3), ones (3,2,3))
+%!error <numeric arrays of the same size> cart2pol ({1,2,3}, [1,2,3], [1,2,3])
+%!error <numeric arrays of the same size> cart2pol ([1,2,3], {1,2,3}, [1,2,3])
+%!error <numeric arrays of the same size> cart2pol ([1,2,3], [1,2,3], {1,2,3})
+%!error <numeric arrays of the same size> cart2pol (ones (3,3,3), 1, ones (3,2,3))
+%!error <numeric arrays of the same size> cart2pol (ones (3,3,3), ones (3,2,3), 1)
+
--- a/scripts/general/cart2sph.m	Mon Feb 01 22:59:43 2016 -0800
+++ b/scripts/general/cart2sph.m	Sun Jan 31 21:05:08 2016 -0800
@@ -1,4 +1,4 @@
-## Copyright (C) 2000-2015 Kai Habel
+## Copyright (C) 2000-2016 Kai Habel
 ##
 ## This file is part of Octave.
 ##
@@ -48,19 +48,18 @@
   endif
 
   if (nargin == 1)
-    if (ismatrix (x) && columns (x) == 3)
-      z = x(:,3);
-      y = x(:,2);
-      x = x(:,1);
-    else
+    if (! (isnumeric (x) && ismatrix (x) && columns (x) == 3))
       error ("cart2sph: matrix input must have 3 columns [X, Y, Z]");
     endif
-  elseif (nargin == 3)
-    if (! ((ismatrix (x) && ismatrix (y) && ismatrix (z))
+    z = x(:,3);
+    y = x(:,2);
+    x = x(:,1);
+  else
+    if (! ((isnumeric (x) && isnumeric (y) && isnumeric (z))
             && (size_equal (x, y) || isscalar (x) || isscalar (y))
             && (size_equal (x, z) || isscalar (x) || isscalar (z))
             && (size_equal (y, z) || isscalar (y) || isscalar (z))))
-      error ("cart2sph: X, Y, Z must be matrices of the same size, or scalar");
+      error ("cart2sph: X, Y, Z must be numeric arrays of the same size, or scalar");
     endif
   endif
 
@@ -116,3 +115,27 @@
 %! S = [0, 0, 0; 0, pi/4, sqrt(2); 0, pi/4, 2*sqrt(2)];
 %! assert (cart2sph (C), S, eps);
 
+%!test
+%! [x, y, z] = meshgrid ([0, 1], [0, 1], [0, 1]);
+%! [t, p, r] = cart2sph (x, y, z);
+%! T(:, :, 1) = [0, 0; pi/2, pi/4];
+%! T(:, :, 2) = T(:, :, 1);
+%! P(:, :, 1) = zeros (2, 2);
+%! P(:, :, 2) = [pi/2, pi/4; pi/4, acos(sqrt(2/3))];
+%! R = sqrt (x .^ 2 + y .^ 2 + z .^ 2);
+%! assert (t, T, eps);
+%! assert (p, P, eps);
+%! assert (r, R, eps);
+
+## Test input validation
+%!error cart2sph ()
+%!error cart2sph (1,2)
+%!error cart2sph (1,2,3,4)
+%!error <matrix input must have 3 columns> cart2sph ({1,2,3})
+%!error <matrix input must have 3 columns> cart2sph (ones (3,3,2))
+%!error <matrix input must have 3 columns> cart2sph ([1,2,3,4])
+%!error <numeric arrays of the same size> cart2sph ({1,2,3}, [1,2,3], [1,2,3])
+%!error <numeric arrays of the same size> cart2sph ([1,2,3], {1,2,3}, [1,2,3])
+%!error <numeric arrays of the same size> cart2sph ([1,2,3], [1,2,3], {1,2,3})
+%!error <numeric arrays of the same size> cart2sph (ones (3,3,3), 1, ones (3,2,3))
+%!error <numeric arrays of the same size> cart2sph (ones (3,3,3), ones (3,2,3), 1)
--- a/scripts/general/pol2cart.m	Mon Feb 01 22:59:43 2016 -0800
+++ b/scripts/general/pol2cart.m	Sun Jan 31 21:05:08 2016 -0800
@@ -1,4 +1,4 @@
-## Copyright (C) 2000-2015 Kai Habel
+## Copyright (C) 2000-2016 Kai Habel
 ##
 ## This file is part of Octave.
 ##
@@ -49,26 +49,26 @@
   endif
 
   if (nargin == 1)
-    if (ismatrix (theta) && (columns (theta) == 2 || columns (theta) == 3))
-      if (columns (theta) == 3)
-        z = theta(:,3);
-      endif
-      r = theta(:,2);
-      theta = theta(:,1);
-    else
+    if (! (isnumeric (theta) && ismatrix (theta)
+           && (columns (theta) == 2 || columns (theta) == 3)))
       error ("pol2cart: matrix input must have 2 or 3 columns [THETA, R (, Z)]");
     endif
+    if (columns (theta) == 3)
+      z = theta(:,3);
+    endif
+    r = theta(:,2);
+    theta = theta(:,1);
   elseif (nargin == 2)
-    if (! ((ismatrix (theta) && ismatrix (r))
+    if (! ((isnumeric (theta) && isnumeric (r))
             && (size_equal (theta, r) || isscalar (theta) || isscalar (r))))
-      error ("pol2cart: arguments must be matrices of same size, or scalar");
+      error ("pol2cart: THETA, R must be numeric arrays of the same size, or scalar");
     endif
   elseif (nargin == 3)
-    if (! ((ismatrix (theta) && ismatrix (r) && ismatrix (z))
+    if (! ((isnumeric (theta) && isnumeric (r) && isnumeric (z))
             && (size_equal (theta, r) || isscalar (theta) || isscalar (r))
             && (size_equal (theta, z) || isscalar (theta) || isscalar (z))
             && (size_equal (r, z) || isscalar (r) || isscalar (z))))
-      error ("pol2cart: arguments must be matrices of same size, or scalar");
+      error ("pol2cart: THETA, R, Z must be numeric arrays of the same size, or scalar");
     endif
   endif
 
@@ -142,3 +142,43 @@
 %! C = [0, 0, 0; 1, 1, 1; 2, 2, 2];
 %! assert (pol2cart (P), C, sqrt (eps));
 
+%!test
+%! r = ones (1, 1, 1, 2);
+%! r(1, 1, 1, 2) = 2;
+%! t = pi/2 * r;
+%! [x, y] = pol2cart (t, r);
+%! X = zeros (1, 1, 1, 2);
+%! X(1, 1, 1, 2) = -2;
+%! Y = zeros (1, 1, 1, 2);
+%! Y(1, 1, 1, 1) = 1;
+%! assert (x, X, 2*eps);
+%! assert (y, Y, 2*eps);
+
+%!test
+%! [t, r, Z] = meshgrid ([0, pi/2], [1, 2], [0, 1]);
+%! [x, y, z] = pol2cart (t, r, Z);
+%! X = zeros(2, 2, 2);
+%! X(:, 1, 1) = [1; 2];
+%! X(:, 1, 2) = [1; 2];
+%! Y = zeros(2, 2, 2);
+%! Y(:, 2, 1) = [1; 2];
+%! Y(:, 2, 2) = [1; 2];
+%! assert (x, X, eps);
+%! assert (y, Y, eps);
+%! assert (z, Z);
+
+## Test input validation
+%!error pol2cart ()
+%!error pol2cart (1,2,3,4)
+%!error <matrix input must have 2 or 3 columns> pol2cart ({1,2,3})
+%!error <matrix input must have 2 or 3 columns> pol2cart (ones (3,3,2))
+%!error <matrix input must have 2 or 3 columns> pol2cart ([1])
+%!error <matrix input must have 2 or 3 columns> pol2cart ([1,2,3,4])
+%!error <numeric arrays of the same size> pol2cart ({1,2,3}, [1,2,3])
+%!error <numeric arrays of the same size> pol2cart ([1,2,3], {1,2,3})
+%!error <numeric arrays of the same size> pol2cart (ones (3,3,3), ones (3,2,3))
+%!error <numeric arrays of the same size> pol2cart ({1,2,3}, [1,2,3], [1,2,3])
+%!error <numeric arrays of the same size> pol2cart ([1,2,3], {1,2,3}, [1,2,3])
+%!error <numeric arrays of the same size> pol2cart ([1,2,3], [1,2,3], {1,2,3})
+%!error <numeric arrays of the same size> pol2cart (ones (3,3,3), 1, ones (3,2,3))
+%!error <numeric arrays of the same size> pol2cart (ones (3,3,3), ones (3,2,3), 1)
--- a/scripts/general/sph2cart.m	Mon Feb 01 22:59:43 2016 -0800
+++ b/scripts/general/sph2cart.m	Sun Jan 31 21:05:08 2016 -0800
@@ -1,4 +1,4 @@
-## Copyright (C) 2000-2015 Kai Habel
+## Copyright (C) 2000-2016 Kai Habel
 ##
 ## This file is part of Octave.
 ##
@@ -48,19 +48,18 @@
   endif
 
   if (nargin == 1)
-    if (ismatrix (theta) && columns (theta) == 3)
-      r = theta(:,3);
-      phi = theta(:,2);
-      theta = theta(:,1);
-    else
+    if (! (isnumeric (theta) && ismatrix (theta) && columns (theta) == 3))
       error ("sph2cart: matrix input must have 3 columns [THETA, PHI, R]");
     endif
-  elseif (nargin == 3)
-    if (! ((ismatrix (theta) && ismatrix (phi) && ismatrix (r))
+    r = theta(:,3);
+    phi = theta(:,2);
+    theta = theta(:,1);
+  else
+    if (! ((isnumeric (theta) && isnumeric (phi) && isnumeric (r))
             && (size_equal (theta, phi) || isscalar (theta) || isscalar (phi))
             && (size_equal (theta, r) || isscalar (theta) || isscalar (r))
             && (size_equal (phi, r) || isscalar (phi) || isscalar (r))))
-      error ("sph2cart: THETA, PHI, and R must be matrices of the same size, or scalar");
+      error ("sph2cart: THETA, PHI, R must be numeric arrays of the same size, or scalar");
     endif
   endif
 
@@ -116,3 +115,29 @@
 %! C = [ 1, 0, 0; 0, 1, 0; -1, 0, 0];
 %! assert (sph2cart (S), C, eps);
 
+%!test
+%! [t, p, r] = meshgrid ([0, pi/2], [0, pi/2], [0, 1]);
+%! [x, y, z] = sph2cart (t, p, r);
+%! X = zeros(2, 2, 2);
+%! X(1, 1, 2) = 1;
+%! Y = zeros(2, 2, 2);
+%! Y(1, 2, 2) = 1;
+%! Z = zeros(2, 2, 2);
+%! Z(2, :, 2) = [1 1];
+%! assert (x, X, eps);
+%! assert (y, Y, eps);
+%! assert (z, Z);
+
+## Test input validation
+%!error sph2cart ()
+%!error sph2cart (1,2)
+%!error sph2cart (1,2,3,4)
+%!error <matrix input must have 3 columns> sph2cart ({1,2,3})
+%!error <matrix input must have 3 columns> sph2cart (ones (3,3,2))
+%!error <matrix input must have 3 columns> sph2cart ([1,2,3,4])
+%!error <numeric arrays of the same size> sph2cart ({1,2,3}, [1,2,3], [1,2,3])
+%!error <numeric arrays of the same size> sph2cart ([1,2,3], {1,2,3}, [1,2,3])
+%!error <numeric arrays of the same size> sph2cart ([1,2,3], [1,2,3], {1,2,3})
+%!error <numeric arrays of the same size> sph2cart (ones (3,3,3), 1, ones (3,2,3))
+%!error <numeric arrays of the same size> sph2cart (ones (3,3,3), ones (3,2,3), 1)
+