# HG changeset patch # User jwe # Date 1191961963 0 # Node ID 2d326000e09b1b233a25a7abed4a171c66f822ba # Parent c7484dcadd4d9bedf4ccf49e44ae07f880e19225 [project @ 2007-10-09 20:32:42 by jwe] diff -r c7484dcadd4d -r 2d326000e09b liboctave/ChangeLog --- a/liboctave/ChangeLog Tue Oct 09 19:59:51 2007 +0000 +++ b/liboctave/ChangeLog Tue Oct 09 20:32:43 2007 +0000 @@ -1,3 +1,8 @@ +2007-10-09 John W. Eaton + + * dSparse.cc (SparseMatrix::all_elements_are_zero): New function. + * dNDArray.cc (NDArray::all_elements_are_zero): New function. + 2007-10-09 David Bateman * Sparse.cc (Sparse Sparse::index (idx_vector&, idx_vector&, diff -r c7484dcadd4d -r 2d326000e09b liboctave/dNDArray.cc --- a/liboctave/dNDArray.cc Tue Oct 09 19:59:51 2007 +0000 +++ b/liboctave/dNDArray.cc Tue Oct 09 20:32:43 2007 +0000 @@ -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 (); diff -r c7484dcadd4d -r 2d326000e09b liboctave/dNDArray.h --- a/liboctave/dNDArray.h Tue Oct 09 19:59:51 2007 +0000 +++ b/liboctave/dNDArray.h Tue Oct 09 20:32:43 2007 +0000 @@ -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; diff -r c7484dcadd4d -r 2d326000e09b liboctave/dSparse.cc --- a/liboctave/dSparse.cc Tue Oct 09 19:59:51 2007 +0000 +++ b/liboctave/dSparse.cc Tue Oct 09 20:32:43 2007 +0000 @@ -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 (); diff -r c7484dcadd4d -r 2d326000e09b liboctave/dSparse.h --- a/liboctave/dSparse.h Tue Oct 09 19:59:51 2007 +0000 +++ b/liboctave/dSparse.h Tue Oct 09 20:32:43 2007 +0000 @@ -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; diff -r c7484dcadd4d -r 2d326000e09b src/ChangeLog --- a/src/ChangeLog Tue Oct 09 19:59:51 2007 +0000 +++ b/src/ChangeLog Tue Oct 09 20:32:43 2007 +0000 @@ -1,5 +1,8 @@ 2007-10-09 John W. Eaton + * 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. diff -r c7484dcadd4d -r 2d326000e09b src/defun.h --- a/src/defun.h Tue Oct 09 19:59:51 2007 +0000 +++ b/src/defun.h Tue Oct 09 20:32:43 2007 +0000 @@ -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 diff -r c7484dcadd4d -r 2d326000e09b src/ov-mapper.cc --- a/src/ov-mapper.cc Tue Oct 09 19:59:51 2007 +0000 +++ b/src/ov-mapper.cc Tue Oct 09 20:32:43 2007 +0000 @@ -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) diff -r c7484dcadd4d -r 2d326000e09b src/ov-mapper.h --- a/src/ov-mapper.h Tue Oct 09 19:59:51 2007 +0000 +++ b/src/ov-mapper.h Tue Oct 09 20:32:43 2007 +0000 @@ -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