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	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  <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	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 ();
--- 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;
--- 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 ();
--- 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;
--- 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  <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	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
--- 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)
--- 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