# HG changeset patch # User jwe # Date 1060178167 0 # Node ID cfbaee1f562f83596f74ef5d5ba43d2633c3f36d # Parent b96f2c55d5a3aba2c69f9edfef5c1aad4769a3d8 [project @ 2003-08-06 13:56:07 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2003-08-06 Heine Kolltveit + + * utils.cc (check_dimensions(Array&, char), + get_dimensions(octave_value&, char, Array&): New functions. + * utils.h (check_dimensions (Array&, char), + get_dimensions (octave_value&, char, Array&)): Provide decl. + + * data.cc (fill_matrix): Also create N-d arrays. + (Fones, Fzeros): Handle more than 2 args to create N-d arrays. + 2003-07-30 John W. Eaton * data.cc (make_diag): Use std::abs instead of our own ABS macro. diff --git a/src/data.cc b/src/data.cc --- a/src/data.cc +++ b/src/data.cc @@ -928,35 +928,86 @@ int nargin = args.length (); + int ndim = 0; + int type = 0; + + Array dims; + + // Check for type information. + + if (nargin > 0 && args(nargin-1).is_string ()) + { + nargin--; + + // XXX FIXME XXX -- allow type of the resulting matrix to be + // specified, e.g. + // + // zeros(n1, n2, ..., 'real') + // zeros(n1, n2, ..., 'complex') + // + // type = get_type (args(nargin).string_value ()); + } + + // determine matrix dimension + switch (nargin) { case 0: - retval = val; + ndim = 0; + type = 0; break; case 1: - { - int nr, nc; - get_dimensions (args(0), fcn, nr, nc); - - if (! error_state) - retval = Matrix (nr, nc, val); - } + get_dimensions (args(0), fcn, dims); break; - case 2: - { - int nr, nc; - get_dimensions (args(0), args(1), fcn, nr, nc); + default: + { + dims.resize (nargin); + + for (int i = 0; i < nargin; i++) + { + dims(i) = args(i).is_empty () ? 0 : args(i).nint_value (); + + if (error_state) + { + error ("%s: expecting scalar arguments", fcn); + break; + } + } + } + break; + } + + if (! error_state) + { + ndim = dims.length (); + + check_dimensions (dims, fcn); - if (! error_state) - retval = Matrix (nr, nc, val); - } - break; + if (! error_state) + { + // Construct either scalar, matrix or N-d array. + + switch (ndim) + { + case 0: + retval = val; + break; - default: - print_usage (fcn); - break; + case 1: + retval = Matrix (dims(0), dims(0), val); + break; + + case 2: + retval = Matrix (dims(0), dims(1), val); + break; + + default: + retval = ArrayN (dims, val); + break; + } + } } return retval; @@ -966,8 +1017,9 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} ones (@var{x})\n\ @deftypefnx {Built-in Function} {} ones (@var{n}, @var{m})\n\ -Return a matrix whose elements are all 1. The arguments are handled\n\ -the same as the arguments for @code{eye}.\n\ +@deftypefnx {Built-in Function} {} ones (@var{n}, @var{m}, @var{k},...)\n\ +Return a matrix or N-dimensional array whose elements are all 1.\n\ +The arguments are handled the same as the arguments for @code{eye}.\n\ \n\ If you need to create a matrix whose values are all the same, you should\n\ use an expression like\n\ @@ -984,8 +1036,9 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} zeros (@var{x})\n\ @deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m})\n\ -Return a matrix whose elements are all 0. The arguments are handled\n\ -the same as the arguments for @code{eye}.\n\ +@deftypefnx {Built-in Function} {} zeros (@var{n}, @var{m}, @var{k},...)\n\ +Return a matrix or N-dimensional array whose elements are all 0.\n\ +The arguments are handled the same as the arguments for @code{eye}.\n\ @end deftypefn") { return fill_matrix (args, 0.0, "zeros"); diff --git a/src/utils.cc b/src/utils.cc --- a/src/utils.cc +++ b/src/utils.cc @@ -766,6 +766,63 @@ } void +check_dimensions (Array& dim, const char *warnfor) +{ + bool neg = false; + + int n = dim.length (); + for (int i = 0; i < dim.length (); i++) + { + if (dim(i) < 0) + { + dim(i) = 0; + neg = true; + } + } + + if (neg && Vwarn_neg_dim_as_zero) + { + warning ("%s: converting negative dimension to zero", warnfor); + } +} + + +void +get_dimensions (const octave_value& a, const char *warn_for, + Array& dim) +{ + if (a.is_scalar_type ()) + { + dim.resize (2); + dim(0) = a.nint_value (); + dim(1) = dim(0); + } + else + { + int nr = a.rows (); + int nc = a.columns (); + + if (nr == 1 || nc == 1) + { + Array v = a.vector_value (); + + if (error_state) + return; + + int n = v.length (); + dim.resize (n); + for (int i = 0; i < n; i++) + dim(i) = NINT (v(i)); + } + else + warning ("%s (A): use %s (size (A)) instead", warn_for, warn_for); + } + + check_dimensions (dim, warn_for); // May set error_state. +} + + +void get_dimensions (const octave_value& a, const char *warn_for, int& nr, int& nc) { diff --git a/src/utils.h b/src/utils.h --- a/src/utils.h +++ b/src/utils.h @@ -67,6 +67,13 @@ extern int check_preference (const std::string& var); extern void +check_dimensions (Array& dim, const char *warnfor); + +extern void +get_dimensions (const octave_value& a, const char *warn_for, + Array& dim); + +extern void get_dimensions (const octave_value& a, const octave_value& b, const char *warn_for, int& nr, int& nc);