1--- a/src/ChangeLog Wed Feb 20 15:52:11 2008 -0500
2+++ b/src/ChangeLog Wed Feb 20 17:39:11 2008 -0500
3@@ -1,4 +1,7 @@
4 2008-02-20 John W. Eaton <jwe@octave.org>
5+
6+ * data.cc (map_d_m, map_m_d, map_m_m, Fatan2, Ffmod):
7+ Handle N-d arrays.
8
9 * ov-bool-mat.h (octave_bool_matrix (const Array2<bool>&)): Delete.
10
1.1--- a/src/data.cc Wed Feb 20 15:52:11 2008 -0500
1.2+++ b/src/data.cc Wed Feb 20 17:39:11 2008 -0500
1.3@@ -130,61 +130,62 @@
1.4
1.5 typedef double (*d_dd_fcn) (double, double);
1.6
1.7-static Matrix
1.8-map_d_m (d_dd_fcn f, double x, const Matrix& y)
1.9+static NDArray
1.10+map_d_m (d_dd_fcn f, double x, const NDArray& y)
1.11 {
1.12- octave_idx_type nr = y.rows ();
1.13- octave_idx_type nc = y.columns ();
1.14+ NDArray retval (y.dims ());
1.15+ double *r_data = retval.fortran_vec ();
1.16
1.17- Matrix retval (nr, nc);
1.18+ const double *y_data = y.data ();
1.19
1.20- for (octave_idx_type j = 0; j < nc; j++)
1.21- for (octave_idx_type i = 0; i < nr; i++)
1.22- {
1.23- OCTAVE_QUIT;
1.24- retval (i, j) = f (x, y (i, j));
1.25- }
1.26+ octave_idx_type nel = y.numel ();
1.27+
1.28+ for (octave_idx_type i = 0; i < nel; i++)
1.29+ {
1.30+ OCTAVE_QUIT;
1.31+ r_data[i] = f (x, y_data[i]);
1.32+ }
1.33
1.34 return retval;
1.35 }
1.36
1.37-static Matrix
1.38-map_m_d (d_dd_fcn f, const Matrix& x, double y)
1.39+static NDArray
1.40+map_m_d (d_dd_fcn f, const NDArray& x, double y)
1.41 {
1.42- octave_idx_type nr = x.rows ();
1.43- octave_idx_type nc = x.columns ();
1.44+ NDArray retval (x.dims ());
1.45+ double *r_data = retval.fortran_vec ();
1.46
1.47- Matrix retval (nr, nc);
1.48+ const double *x_data = x.data ();
1.49
1.50- for (octave_idx_type j = 0; j < nc; j++)
1.51- for (octave_idx_type i = 0; i < nr; i++)
1.52- {
1.53- OCTAVE_QUIT;
1.54- retval (i, j) = f (x (i, j), y);
1.55- }
1.56+ octave_idx_type nel = x.numel ();
1.57+
1.58+ for (octave_idx_type i = 0; i < nel; i++)
1.59+ {
1.60+ OCTAVE_QUIT;
1.61+ r_data[i] = f (x_data[i], y);
1.62+ }
1.63
1.64 return retval;
1.65 }
1.66
1.67-static Matrix
1.68-map_m_m (d_dd_fcn f, const Matrix& x, const Matrix& y)
1.69+static NDArray
1.70+map_m_m (d_dd_fcn f, const NDArray& x, const NDArray& y)
1.71 {
1.72- octave_idx_type x_nr = x.rows ();
1.73- octave_idx_type x_nc = x.columns ();
1.74+ assert (x.dims () == y.dims ());
1.75
1.76- octave_idx_type y_nr = y.rows ();
1.77- octave_idx_type y_nc = y.columns ();
1.78+ NDArray retval (x.dims ());
1.79+ double *r_data = retval.fortran_vec ();
1.80
1.81- assert (x_nr == y_nr && x_nc == y_nc);
1.82+ const double *x_data = x.data ();
1.83+ const double *y_data = y.data ();
1.84
1.85- Matrix retval (x_nr, x_nc);
1.86+ octave_idx_type nel = x.numel ();
1.87
1.88- for (octave_idx_type j = 0; j < x_nc; j++)
1.89- for (octave_idx_type i = 0; i < x_nr; i++)
1.90- {
1.91- OCTAVE_QUIT;
1.92- retval (i, j) = f (x (i, j), y (i, j));
1.93- }
1.94+ for (octave_idx_type i = 0; i < nel; i++)
1.95+ {
1.96+ OCTAVE_QUIT;
1.97+ r_data[i] = f (x_data[i], y_data[i]);
1.98+ }
1.99
1.100 return retval;
1.101 }
1.102@@ -423,29 +424,18 @@
1.103
1.104 if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
1.105 {
1.106- if (args(0).is_integer_type () || args(0).is_integer_type ())
1.107+ if (args(0).is_integer_type () || args(1).is_integer_type ())
1.108 error ("atan2: not defined for integer types");
1.109 else
1.110 {
1.111 octave_value arg_y = args(0);
1.112 octave_value arg_x = args(1);
1.113
1.114- octave_idx_type y_nr = arg_y.rows ();
1.115- octave_idx_type y_nc = arg_y.columns ();
1.116+ dim_vector y_dims = arg_y.dims ();
1.117+ dim_vector x_dims = arg_x.dims ();
1.118
1.119- octave_idx_type x_nr = arg_x.rows ();
1.120- octave_idx_type x_nc = arg_x.columns ();
1.121-
1.122- int arg_y_empty = empty_arg ("atan2", y_nr, y_nc);
1.123- int arg_x_empty = empty_arg ("atan2", x_nr, x_nc);
1.124-
1.125- if (arg_y_empty > 0 && arg_x_empty > 0)
1.126- return octave_value (Matrix ());
1.127- else if (arg_y_empty || arg_x_empty)
1.128- return retval;
1.129-
1.130- octave_idx_type y_is_scalar = (y_nr == 1 && y_nc == 1);
1.131- octave_idx_type x_is_scalar = (x_nr == 1 && x_nc == 1);
1.132+ bool y_is_scalar = y_dims.all_ones ();
1.133+ bool x_is_scalar = x_dims.all_ones ();
1.134
1.135 if (y_is_scalar && x_is_scalar)
1.136 {
1.137@@ -474,7 +464,7 @@
1.138 }
1.139 else
1.140 {
1.141- Matrix x = arg_x.matrix_value ();
1.142+ NDArray x = arg_x.array_value ();
1.143
1.144 if (! error_state)
1.145 retval = map_d_m (atan2, y, x);
1.146@@ -497,7 +487,7 @@
1.147 }
1.148 else
1.149 {
1.150- Matrix y = arg_y.matrix_value ();
1.151+ NDArray y = arg_y.array_value ();
1.152
1.153 if (! error_state)
1.154 {
1.155@@ -508,7 +498,7 @@
1.156 }
1.157 }
1.158 }
1.159- else if (y_nr == x_nr && y_nc == x_nc)
1.160+ else if (y_dims == x_dims)
1.161 {
1.162 if (arg_y.is_sparse_type () || arg_x.is_sparse_type ())
1.163 {
1.164@@ -524,11 +514,11 @@
1.165 }
1.166 else
1.167 {
1.168- Matrix y = arg_y.matrix_value ();
1.169+ NDArray y = arg_y.array_value ();
1.170
1.171 if (! error_state)
1.172 {
1.173- Matrix x = arg_x.matrix_value ();
1.174+ NDArray x = arg_x.array_value ();
1.175
1.176 if (! error_state)
1.177 retval = map_m_m (atan2, y, x);
1.178@@ -545,6 +535,14 @@
1.179 return retval;
1.180 }
1.181
1.182+/*
1.183+%! assert (size (atan2 (zeros (0, 2), zeros (0, 2))), [0, 2])
1.184+%! assert (size (atan2 (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
1.185+%! assert (size (atan2 (rand (2, 3, 4), 1), [2, 3, 4])
1.186+%! assert (size (atan2 (1, rand (2, 3, 4)), [2, 3, 4])
1.187+%! assert (size (atan2 (1, 2), [1, 1])
1.188+*/
1.189+
1.190 DEFUN (fmod, args, ,
1.191 "-*- texinfo -*-\n\
1.192 @deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})\n\
1.193@@ -559,25 +557,14 @@
1.194
1.195 if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
1.196 {
1.197- octave_value arg_x = args(0);
1.198- octave_value arg_y = args(1);
1.199+ octave_value arg_y = args(0);
1.200+ octave_value arg_x = args(1);
1.201
1.202- octave_idx_type y_nr = arg_y.rows ();
1.203- octave_idx_type y_nc = arg_y.columns ();
1.204+ dim_vector y_dims = arg_y.dims ();
1.205+ dim_vector x_dims = arg_x.dims ();
1.206
1.207- octave_idx_type x_nr = arg_x.rows ();
1.208- octave_idx_type x_nc = arg_x.columns ();
1.209-
1.210- int arg_y_empty = empty_arg ("fmod", y_nr, y_nc);
1.211- int arg_x_empty = empty_arg ("fmod", x_nr, x_nc);
1.212-
1.213- if (arg_y_empty > 0 && arg_x_empty > 0)
1.214- return octave_value (Matrix ());
1.215- else if (arg_y_empty || arg_x_empty)
1.216- return retval;
1.217-
1.218- octave_idx_type y_is_scalar = (y_nr == 1 && y_nc == 1);
1.219- octave_idx_type x_is_scalar = (x_nr == 1 && x_nc == 1);
1.220+ bool y_is_scalar = y_dims.all_ones ();
1.221+ bool x_is_scalar = x_dims.all_ones ();
1.222
1.223 if (y_is_scalar && x_is_scalar)
1.224 {
1.225@@ -606,7 +593,7 @@
1.226 }
1.227 else
1.228 {
1.229- Matrix x = arg_x.matrix_value ();
1.230+ NDArray x = arg_x.array_value ();
1.231
1.232 if (! error_state)
1.233 retval = map_m_d (fmod, x, y);
1.234@@ -629,7 +616,7 @@
1.235 }
1.236 else
1.237 {
1.238- Matrix y = arg_y.matrix_value ();
1.239+ NDArray y = arg_y.array_value ();
1.240
1.241 if (! error_state)
1.242 {
1.243@@ -640,7 +627,7 @@
1.244 }
1.245 }
1.246 }
1.247- else if (y_nr == x_nr && y_nc == x_nc)
1.248+ else if (y_dims == x_dims)
1.249 {
1.250 if (arg_y.is_sparse_type () || arg_x.is_sparse_type ())
1.251 {
1.252@@ -656,11 +643,11 @@
1.253 }
1.254 else
1.255 {
1.256- Matrix y = arg_y.matrix_value ();
1.257+ NDArray y = arg_y.array_value ();
1.258
1.259 if (! error_state)
1.260 {
1.261- Matrix x = arg_x.matrix_value ();
1.262+ NDArray x = arg_x.array_value ();
1.263
1.264 if (! error_state)
1.265 retval = map_m_m (fmod, x, y);
1.266@@ -675,6 +662,14 @@
1.267
1.268 return retval;
1.269 }
1.270+
1.271+/*
1.272+%! assert (size (fmod (zeros (0, 2), zeros (0, 2))), [0, 2])
1.273+%! assert (size (fmod (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
1.274+%! assert (size (fmod (rand (2, 3, 4), 1), [2, 3, 4])
1.275+%! assert (size (fmod (1, rand (2, 3, 4)), [2, 3, 4])
1.276+%! assert (size (fmod (1, 2), [1, 1])
1.277+*/
1.278
1.279 #define NATIVE_REDUCTION_1(FCN, TYPE, DIM) \
1.280 (arg.is_ ## TYPE ## _type ()) \