changeset 7506:798b0a00e80c

atan2, fmod: accept N-d arrays
author John W. Eaton <jwe@octave.org>
date Wed, 20 Feb 2008 17:39:11 -0500
parents f5005d9510f4
children bc6573d2fa40
files src/ChangeLog src/data.cc
diffstat 2 files changed, 88 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Feb 20 15:52:11 2008 -0500
+++ b/src/ChangeLog	Wed Feb 20 17:39:11 2008 -0500
@@ -1,5 +1,8 @@
 2008-02-20  John W. Eaton  <jwe@octave.org>
 
+	* data.cc (map_d_m, map_m_d, map_m_m, Fatan2, Ffmod):
+	Handle N-d arrays.
+
 	* ov-bool-mat.h (octave_bool_matrix (const Array2<bool>&)): Delete.
 
 2008-02-20  David Bateman  <dbateman@free.fr>
--- a/src/data.cc	Wed Feb 20 15:52:11 2008 -0500
+++ b/src/data.cc	Wed Feb 20 17:39:11 2008 -0500
@@ -130,61 +130,62 @@
 
 typedef double (*d_dd_fcn) (double, double);
 
-static Matrix
-map_d_m (d_dd_fcn f, double x, const Matrix& y)
+static NDArray
+map_d_m (d_dd_fcn f, double x, const NDArray& y)
 {
-  octave_idx_type nr = y.rows ();
-  octave_idx_type nc = y.columns ();
-
-  Matrix retval (nr, nc);
-
-  for (octave_idx_type j = 0; j < nc; j++)
-    for (octave_idx_type i = 0; i < nr; i++)
-      {
-	OCTAVE_QUIT;
-	retval (i, j) = f (x, y (i, j));
-      }
+  NDArray retval (y.dims ());
+  double *r_data = retval.fortran_vec ();
+
+  const double *y_data = y.data ();
+
+  octave_idx_type nel = y.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x, y_data[i]);
+    }
 
   return retval;
 }
 
-static Matrix
-map_m_d (d_dd_fcn f, const Matrix& x, double y)
+static NDArray
+map_m_d (d_dd_fcn f, const NDArray& x, double y)
 {
-  octave_idx_type nr = x.rows ();
-  octave_idx_type nc = x.columns ();
-
-  Matrix retval (nr, nc);
-
-  for (octave_idx_type j = 0; j < nc; j++)
-    for (octave_idx_type i = 0; i < nr; i++)
-      {
-	OCTAVE_QUIT;
-	retval (i, j) = f (x (i, j), y);
-      }
+  NDArray retval (x.dims ());
+  double *r_data = retval.fortran_vec ();
+
+  const double *x_data = x.data ();
+
+  octave_idx_type nel = x.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x_data[i], y);
+    }
 
   return retval;
 }
 
-static Matrix
-map_m_m (d_dd_fcn f, const Matrix& x, const Matrix& y)
+static NDArray
+map_m_m (d_dd_fcn f, const NDArray& x, const NDArray& y)
 {
-  octave_idx_type x_nr = x.rows ();
-  octave_idx_type x_nc = x.columns ();
-
-  octave_idx_type y_nr = y.rows ();
-  octave_idx_type y_nc = y.columns ();
-
-  assert (x_nr == y_nr && x_nc == y_nc);
-
-  Matrix retval (x_nr, x_nc);
-
-  for (octave_idx_type j = 0; j < x_nc; j++)
-    for (octave_idx_type i = 0; i < x_nr; i++)
-      {
-	OCTAVE_QUIT;
-	retval (i, j) = f (x (i, j), y (i, j));
-      }
+  assert (x.dims () == y.dims ());
+
+  NDArray retval (x.dims ());
+  double *r_data = retval.fortran_vec ();
+
+  const double *x_data = x.data ();
+  const double *y_data = y.data ();
+
+  octave_idx_type nel = x.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      OCTAVE_QUIT;
+      r_data[i] = f (x_data[i], y_data[i]);
+    }
 
   return retval;
 }
@@ -423,29 +424,18 @@
 
   if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
     {
-      if (args(0).is_integer_type () || args(0).is_integer_type ())
+      if (args(0).is_integer_type () || args(1).is_integer_type ())
 	error ("atan2: not defined for integer types");
       else
 	{
 	  octave_value arg_y = args(0);
 	  octave_value arg_x = args(1);
 
-	  octave_idx_type y_nr = arg_y.rows ();
-	  octave_idx_type y_nc = arg_y.columns ();
-
-	  octave_idx_type x_nr = arg_x.rows ();
-	  octave_idx_type x_nc = arg_x.columns ();
-
-	  int arg_y_empty = empty_arg ("atan2", y_nr, y_nc);
-	  int arg_x_empty = empty_arg ("atan2", x_nr, x_nc);
-
-	  if (arg_y_empty > 0 && arg_x_empty > 0)
-	    return octave_value (Matrix ());
-	  else if (arg_y_empty || arg_x_empty)
-	    return retval;
-
-	  octave_idx_type y_is_scalar = (y_nr == 1 && y_nc == 1);
-	  octave_idx_type x_is_scalar = (x_nr == 1 && x_nc == 1);
+	  dim_vector y_dims = arg_y.dims ();
+	  dim_vector x_dims = arg_x.dims ();
+
+	  bool y_is_scalar = y_dims.all_ones ();
+	  bool x_is_scalar = x_dims.all_ones ();
 
 	  if (y_is_scalar && x_is_scalar)
 	    {
@@ -474,7 +464,7 @@
 		    }
 		  else
 		    {
-		      Matrix x = arg_x.matrix_value ();
+		      NDArray x = arg_x.array_value ();
 
 		      if (! error_state)
 			retval = map_d_m (atan2, y, x);
@@ -497,7 +487,7 @@
 		}
 	      else
 		{
-		  Matrix y = arg_y.matrix_value ();
+		  NDArray y = arg_y.array_value ();
 
 		  if (! error_state)
 		    {
@@ -508,7 +498,7 @@
 		    }
 		}
 	    }
-	  else if (y_nr == x_nr && y_nc == x_nc)
+	  else if (y_dims == x_dims)
 	    {
 	      if (arg_y.is_sparse_type () || arg_x.is_sparse_type ())
 		{
@@ -524,11 +514,11 @@
 		}
 	      else
 		{
-		  Matrix y = arg_y.matrix_value ();
+		  NDArray y = arg_y.array_value ();
 
 		  if (! error_state)
 		    {
-		      Matrix x = arg_x.matrix_value ();
+		      NDArray x = arg_x.array_value ();
 
 		      if (! error_state)
 			retval = map_m_m (atan2, y, x);
@@ -545,6 +535,14 @@
   return retval;
 }
 
+/*
+%! assert (size (atan2 (zeros (0, 2), zeros (0, 2))), [0, 2])
+%! assert (size (atan2 (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
+%! assert (size (atan2 (rand (2, 3, 4), 1), [2, 3, 4])
+%! assert (size (atan2 (1, rand (2, 3, 4)), [2, 3, 4])
+%! assert (size (atan2 (1, 2), [1, 1])
+*/
+
 DEFUN (fmod, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})\n\
@@ -559,25 +557,14 @@
 
   if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
     {
-      octave_value arg_x = args(0);
-      octave_value arg_y = args(1);
-
-      octave_idx_type y_nr = arg_y.rows ();
-      octave_idx_type y_nc = arg_y.columns ();
-
-      octave_idx_type x_nr = arg_x.rows ();
-      octave_idx_type x_nc = arg_x.columns ();
-
-      int arg_y_empty = empty_arg ("fmod", y_nr, y_nc);
-      int arg_x_empty = empty_arg ("fmod", x_nr, x_nc);
-
-      if (arg_y_empty > 0 && arg_x_empty > 0)
-	return octave_value (Matrix ());
-      else if (arg_y_empty || arg_x_empty)
-	return retval;
-
-      octave_idx_type y_is_scalar = (y_nr == 1 && y_nc == 1);
-      octave_idx_type x_is_scalar = (x_nr == 1 && x_nc == 1);
+      octave_value arg_y = args(0);
+      octave_value arg_x = args(1);
+
+      dim_vector y_dims = arg_y.dims ();
+      dim_vector x_dims = arg_x.dims ();
+
+      bool y_is_scalar = y_dims.all_ones ();
+      bool x_is_scalar = x_dims.all_ones ();
 
       if (y_is_scalar && x_is_scalar)
 	{
@@ -606,7 +593,7 @@
 		}
 	      else
 		{
-		  Matrix x = arg_x.matrix_value ();
+		  NDArray x = arg_x.array_value ();
 
 		  if (! error_state)
 		    retval = map_m_d (fmod, x, y);
@@ -629,7 +616,7 @@
 	    }
 	  else
 	    {
-	      Matrix y = arg_y.matrix_value ();
+	      NDArray y = arg_y.array_value ();
 
 	      if (! error_state)
 		{
@@ -640,7 +627,7 @@
 		}
 	    }
 	}
-      else if (y_nr == x_nr && y_nc == x_nc)
+      else if (y_dims == x_dims)
 	{
 	  if (arg_y.is_sparse_type () || arg_x.is_sparse_type ())
 	    {
@@ -656,11 +643,11 @@
 	    }
 	  else
 	    {
-	      Matrix y = arg_y.matrix_value ();
+	      NDArray y = arg_y.array_value ();
 
 	      if (! error_state)
 		{
-		  Matrix x = arg_x.matrix_value ();
+		  NDArray x = arg_x.array_value ();
 
 		  if (! error_state)
 		    retval = map_m_m (fmod, x, y);
@@ -676,6 +663,14 @@
   return retval;
 }
 
+/*
+%! assert (size (fmod (zeros (0, 2), zeros (0, 2))), [0, 2])
+%! assert (size (fmod (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
+%! assert (size (fmod (rand (2, 3, 4), 1), [2, 3, 4])
+%! assert (size (fmod (1, rand (2, 3, 4)), [2, 3, 4])
+%! assert (size (fmod (1, 2), [1, 1])
+*/
+
 #define NATIVE_REDUCTION_1(FCN, TYPE, DIM) \
   (arg.is_ ## TYPE ## _type ()) \
     { \