Mercurial > hg > octave-lyh
changeset 6989:2d326000e09b
[project @ 2007-10-09 20:32:42 by jwe]
author | jwe |
---|---|
date | Tue, 09 Oct 2007 20:32:43 +0000 |
parents | c7484dcadd4d |
children | 9dc99ab00c86 |
files | liboctave/ChangeLog liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/dSparse.cc liboctave/dSparse.h src/ChangeLog src/defun.h src/ov-mapper.cc src/ov-mapper.h |
diffstat | 9 files changed, 72 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,8 @@ +2007-10-09 John W. Eaton <jwe@octave.org> + + * dSparse.cc (SparseMatrix::all_elements_are_zero): New function. + * dNDArray.cc (NDArray::all_elements_are_zero): New function. + 2007-10-09 David Bateman <dbateman@free.fr> * Sparse.cc (Sparse<T> Sparse<T>::index (idx_vector&, idx_vector&,
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -546,6 +546,18 @@ } bool +NDArray::all_elements_are_zero (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + if (elem (i) != 0) + return false; + + return true; +} + +bool NDArray::all_elements_are_int_or_inf_or_nan (void) const { octave_idx_type nel = nelem ();
--- a/liboctave/dNDArray.h +++ b/liboctave/dNDArray.h @@ -66,6 +66,7 @@ bool any_element_is_negative (bool = false) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const; + bool all_elements_are_zero (void) const; bool all_elements_are_int_or_inf_or_nan (void) const; bool all_integers (double& max_val, double& min_val) const; bool too_large_for_float (void) const;
--- a/liboctave/dSparse.cc +++ b/liboctave/dSparse.cc @@ -7651,6 +7651,18 @@ } bool +SparseMatrix::all_elements_are_zero (void) const +{ + octave_idx_type nel = nnz (); + + for (octave_idx_type i = 0; i < nel; i++) + if (data (i) != 0) + return false; + + return true; +} + +bool SparseMatrix::all_elements_are_int_or_inf_or_nan (void) const { octave_idx_type nel = nnz ();
--- a/liboctave/dSparse.h +++ b/liboctave/dSparse.h @@ -376,6 +376,7 @@ bool any_element_is_negative (bool = false) const; bool any_element_is_inf_or_nan (void) const; + bool all_elements_are_zero (void) const; bool all_elements_are_int_or_inf_or_nan (void) const; bool all_integers (double& max_val, double& min_val) const; bool too_large_for_float (void) const;
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2007-10-09 John W. Eaton <jwe@octave.org> + * ov-mapper.cc (octave_mapper::apply): If possible, use + d_d_map_fcn to handle complex values which have imag(z) == 0. + * DLD-FUNCTIONS/urlwrite.cc (Furlwrite, Furlread) [! HAVE_CURL]: Throw error instead of returning empty string hiding error message in third return value.
--- a/src/defun.h +++ b/src/defun.h @@ -87,7 +87,7 @@ // d_d_map is a pointer to a function that should be called for real // arguments that are expected to create real results. // -// d_c_map is a pointer to a function that should be called for +// c_d_map is a pointer to a function that should be called for // complex arguments that are expected to create real results. // // c_c_map is a pointer to a function that should be called for @@ -112,10 +112,10 @@ // doc is the simple help text for the function. #define DEFUN_MAPPER(name, ch_map, d_b_map, c_b_map, d_d_map, \ - d_c_map, c_c_map, lo, hi, ch_map_flag, \ + c_d_map, c_c_map, lo, hi, ch_map_flag, \ can_ret_cmplx_for_real, doc) \ DEFUN_MAPPER_INTERNAL (name, ch_map, d_b_map, c_b_map, d_d_map, \ - d_c_map, c_c_map, lo, hi, ch_map_flag, \ + c_d_map, c_c_map, lo, hi, ch_map_flag, \ can_ret_cmplx_for_real, doc) // Make alias another name for the existing function name. This macro
--- a/src/ov-mapper.cc +++ b/src/ov-mapper.cc @@ -295,16 +295,23 @@ } else if (arg.is_complex_type ()) { + // In the following, we use d_d_map_fcn to handle the case of + // imag (z) == 0. This can happen when a complex value is not + // narrowed to a real value automatically, possibly due to some + // imaginary parts being -0. + if (arg.is_scalar_type ()) { Complex c = arg.complex_value (); - if (d_c_map_fcn) - retval = d_c_map_fcn (c); + if (c_d_map_fcn) + retval = c_d_map_fcn (c); else if (c_c_map_fcn) retval = c_c_map_fcn (c); else if (c_b_map_fcn) retval = c_b_map_fcn (c); + else if (d_d_map_fcn && imag (c) == 0) + retval = d_d_map_fcn (real (c)); else error ("%s: unable to handle complex arguments", name().c_str ()); @@ -316,8 +323,8 @@ if (error_state) return retval; - if (d_c_map_fcn) - SPARSE_MAPPER_LOOP (SparseMatrix, double, d_c_map_fcn, cm); + if (c_d_map_fcn) + SPARSE_MAPPER_LOOP (SparseMatrix, double, c_d_map_fcn, cm); else if (c_c_map_fcn) SPARSE_MAPPER_LOOP (SparseComplexMatrix, Complex, c_c_map_fcn, cm); @@ -325,8 +332,15 @@ SPARSE_MAPPER_LOOP (SparseBoolMatrix, bool, c_b_map_fcn, cm); else - error ("%s: unable to handle complex arguments", - name().c_str ()); + { + SparseMatrix im = imag (cm); + + if (d_d_map_fcn && im.all_elements_are_zero ()) + SPARSE_MAPPER_LOOP (SparseMatrix, double, d_d_map_fcn, real (cm)); + else + error ("%s: unable to handle complex arguments", + name().c_str ()); + } } else { @@ -335,15 +349,22 @@ if (error_state) return retval; - if (d_c_map_fcn) - MAPPER_LOOP (NDArray, d_c_map_fcn, cm); + if (c_d_map_fcn) + MAPPER_LOOP (NDArray, c_d_map_fcn, cm); else if (c_c_map_fcn) MAPPER_LOOP (ComplexNDArray, c_c_map_fcn, cm); else if (c_b_map_fcn) MAPPER_LOOP (boolNDArray, c_b_map_fcn, cm); else - error ("%s: unable to handle complex arguments", - name().c_str ()); + { + NDArray im = imag (cm); + + if (d_d_map_fcn && im.all_elements_are_zero ()) + MAPPER_LOOP (NDArray, d_d_map_fcn, real (cm)); + else + error ("%s: unable to handle complex arguments", + name().c_str ()); + } } } else if (ch_map_fcn)
--- a/src/ov-mapper.h +++ b/src/ov-mapper.h @@ -46,18 +46,18 @@ typedef bool (*d_b_mapper) (double); typedef bool (*c_b_mapper) (const Complex&); typedef double (*d_d_mapper) (double); - typedef double (*d_c_mapper) (const Complex&); + typedef double (*c_d_mapper) (const Complex&); typedef Complex (*c_c_mapper) (const Complex&); octave_mapper (ch_mapper ch, d_b_mapper db, c_b_mapper cb, - d_d_mapper dd, d_c_mapper dc, + d_d_mapper dd, c_d_mapper dc, c_c_mapper cc, double ll, double ul, int cmf, bool crcfr, const std::string& nm = std::string (), const std::string& ds = std::string ()) : octave_function (nm, ds), ch_map_fcn (ch), d_b_map_fcn (db), c_b_map_fcn (cb), - d_d_map_fcn (dd), d_c_map_fcn (dc), c_c_map_fcn (cc), + d_d_map_fcn (dd), c_d_map_fcn (dc), c_c_map_fcn (cc), lower_limit (ll), upper_limit (ul), ch_map_flag (cmf), can_ret_cmplx_for_real (crcfr) { } @@ -89,7 +89,7 @@ d_b_mapper d_b_map_fcn; c_b_mapper c_b_map_fcn; d_d_mapper d_d_map_fcn; - d_c_mapper d_c_map_fcn; + c_d_mapper c_d_map_fcn; c_c_mapper c_c_map_fcn; // If flag is nonzero and we are not calling ch_map_fcn, lower_limit