help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

1 & nan


From: John W. Eaton
Subject: 1 & nan
Date: Fri, 11 Jul 2008 14:57:52 -0400

On 11-Jul-2008, G.. wrote:

| Is there a particular reason that
| 
| 1 & nan = 1
| 
| while 1 +/* nan = nan?

I checked in the following change to the default Mercurial branch to
make Octave's behavior more compatible with Matlab in this case.

jwe

# HG changeset patch
# User John W. Eaton <address@hidden>
# Date 1215802590 14400
# Node ID 935be827eaf8fbbb44f7eb34a5951a893e436724
# Parent  fcc70f30fe31cd4bc694ce773df17bb69131f8c1
error for NaN values in & and | expressions

diff --git a/liboctave/Array-util.cc b/liboctave/Array-util.cc
--- a/liboctave/Array-util.cc
+++ b/liboctave/Array-util.cc
@@ -480,6 +480,11 @@
   return pva->pidx > pvb->pidx;
 }
 
+void
+gripe_nan_to_logical_conversion (void)
+{
+  (*current_liboctave_error_handler) ("invalid conversion of NaN to logical");
+}
 
 void
 gripe_nonconformant (const char *op, int op1_len, int op2_len)
diff --git a/liboctave/Array-util.h b/liboctave/Array-util.h
--- a/liboctave/Array-util.h
+++ b/liboctave/Array-util.h
@@ -89,6 +89,8 @@
 
 extern int OCTAVE_API permute_vector_compare (const void *a, const void *b);
 
+extern void OCTAVE_API gripe_nan_to_logical_conversion (void);
+
 extern void OCTAVE_API gripe_nonconformant (const char *op, int op1_len, int 
op2_len);
 
 extern void OCTAVE_API gripe_nonconformant (const char *op, int op1_nr, int 
op1_nc,
diff --git a/liboctave/CMatrix.cc b/liboctave/CMatrix.cc
--- a/liboctave/CMatrix.cc
+++ b/liboctave/CMatrix.cc
@@ -3302,6 +3302,23 @@
 }
 
 bool
+ComplexMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+       Complex val = elem (i, j);
+       if (xisnan (val))
+         return true;
+      }
+
+  return false;
+}
+
+bool
 ComplexMatrix::any_element_is_inf_or_nan (void) const
 {
   octave_idx_type nr = rows ();
diff --git a/liboctave/CMatrix.h b/liboctave/CMatrix.h
--- a/liboctave/CMatrix.h
+++ b/liboctave/CMatrix.h
@@ -327,6 +327,7 @@
   ComplexMatrix map (cmapper fcn) const;
   boolMatrix map (bmapper fcn) const;
 
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
   bool all_integers (double& max_val, double& min_val) const;
diff --git a/liboctave/CNDArray.cc b/liboctave/CNDArray.cc
--- a/liboctave/CNDArray.cc
+++ b/liboctave/CNDArray.cc
@@ -495,6 +495,20 @@
 }
 
 // FIXME -- this is not quite the right thing.
+
+bool
+ComplexNDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = elem (i);
+      if (xisnan (val))
+       return true;
+    }
+  return false;
+}
 
 bool
 ComplexNDArray::any_element_is_inf_or_nan (void) const
diff --git a/liboctave/CNDArray.h b/liboctave/CNDArray.h
--- a/liboctave/CNDArray.h
+++ b/liboctave/CNDArray.h
@@ -64,6 +64,7 @@
 
   // FIXME -- this is not quite the right thing.
 
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
   bool all_integers (double& max_val, double& min_val) const;
diff --git a/liboctave/CSparse.cc b/liboctave/CSparse.cc
--- a/liboctave/CSparse.cc
+++ b/liboctave/CSparse.cc
@@ -7179,6 +7179,21 @@
 // other operations
 
 bool
+SparseComplexMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      Complex val = data (i);
+      if (xisnan (val))
+       return true;
+    }
+
+  return false;
+}
+
+bool
 SparseComplexMatrix::any_element_is_inf_or_nan (void) const
 {
   octave_idx_type nel = nnz ();
diff --git a/liboctave/CSparse.h b/liboctave/CSparse.h
--- a/liboctave/CSparse.h
+++ b/liboctave/CSparse.h
@@ -402,6 +402,7 @@
 
   SparseComplexMatrix ipermute (const Array<octave_idx_type>& vec) const;
 
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
   bool all_integers (double& max_val, double& min_val) const;
diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,19 @@
+2008-07-11  John W. Eaton  <address@hidden>
+
+       * mx-op-defs.h (MS_BOOL_OP, SM_BOOL_OP, MM_BOOL_OP, NDS_BOOL_OP,
+       SND_BOOL_OP, NDND_BOOL_OP): Detect NaN values.
+       * Array-util.cc (gripe_nan_to_logical_conversion): New function.
+       * Array-util.h: Provide decl.
+       * oct-inttypes.h (xisnan (octave_int<T>)): New function.
+       * lo-mappers.h (xisnan (bool), xisnan (char)): New inline functions.
+
+       * CMatrix.cc, CNDArray.cc, CSparse.cc, dMatrix.cc, dNDArray.cc,
+       dSparse.cc, fCMatrix.cc, fCNDArray.cc, fMatrix.cc, fNDArray.cc:
+       New member function, any_element_is_nan.
+       * CMatrix.h, CNDArray.h, CSparse.h, dMatrix.h, dNDArray.h,
+       dSparse.h, fCMatrix.h, fCNDArray.h, fMatrix.h, fNDArray.h:
+       Provide decl.
+
 2008-07-10  David Bateman  <address@hidden>
 
        * dNDArray.cc (NDArray::NDArray (const Array<octave_idx_type>&,
diff --git a/liboctave/dMatrix.cc b/liboctave/dMatrix.cc
--- a/liboctave/dMatrix.cc
+++ b/liboctave/dMatrix.cc
@@ -2849,6 +2849,20 @@
   return false;
 }
 
+bool
+Matrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisnan (val))
+       return true;
+    }
+
+  return false;
+}
 
 bool
 Matrix::any_element_is_inf_or_nan (void) const
diff --git a/liboctave/dMatrix.h b/liboctave/dMatrix.h
--- a/liboctave/dMatrix.h
+++ b/liboctave/dMatrix.h
@@ -282,6 +282,7 @@
   boolMatrix map (bmapper fcn) const;
 
   bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool any_element_not_one_or_zero (void) const;
   bool all_elements_are_int_or_inf_or_nan (void) const;
diff --git a/liboctave/dNDArray.cc b/liboctave/dNDArray.cc
--- a/liboctave/dNDArray.cc
+++ b/liboctave/dNDArray.cc
@@ -556,6 +556,20 @@
   return false;
 }
 
+bool
+NDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = elem (i);
+      if (xisnan (val))
+       return true;
+    }
+
+  return false;
+}
 
 bool
 NDArray::any_element_is_inf_or_nan (void) const
diff --git a/liboctave/dNDArray.h b/liboctave/dNDArray.h
--- a/liboctave/dNDArray.h
+++ b/liboctave/dNDArray.h
@@ -70,6 +70,7 @@
   boolNDArray operator ! (void) const;
 
   bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) 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;
diff --git a/liboctave/dSparse.cc b/liboctave/dSparse.cc
--- a/liboctave/dSparse.cc
+++ b/liboctave/dSparse.cc
@@ -7237,6 +7237,21 @@
 }
 
 bool
+SparseMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nnz ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      double val = data (i);
+      if (xisnan (val))
+       return true;
+    }
+
+  return false;
+}
+
+bool
 SparseMatrix::any_element_is_inf_or_nan (void) const
 {
   octave_idx_type nel = nnz ();
diff --git a/liboctave/dSparse.h b/liboctave/dSparse.h
--- a/liboctave/dSparse.h
+++ b/liboctave/dSparse.h
@@ -372,6 +372,7 @@
   // other operations
 
   bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) 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;
diff --git a/liboctave/fCMatrix.cc b/liboctave/fCMatrix.cc
--- a/liboctave/fCMatrix.cc
+++ b/liboctave/fCMatrix.cc
@@ -3295,6 +3295,23 @@
 }
 
 bool
+FloatComplexMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+
+  for (octave_idx_type j = 0; j < nc; j++)
+    for (octave_idx_type i = 0; i < nr; i++)
+      {
+       FloatComplex val = elem (i, j);
+       if (xisnan (val))
+         return true;
+      }
+
+  return false;
+}
+
+bool
 FloatComplexMatrix::any_element_is_inf_or_nan (void) const
 {
   octave_idx_type nr = rows ();
diff --git a/liboctave/fCMatrix.h b/liboctave/fCMatrix.h
--- a/liboctave/fCMatrix.h
+++ b/liboctave/fCMatrix.h
@@ -327,6 +327,7 @@
   FloatComplexMatrix map (cmapper fcn) const;
   boolMatrix map (bmapper fcn) const;
 
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
   bool all_integers (float& max_val, float& min_val) const;
diff --git a/liboctave/fCNDArray.cc b/liboctave/fCNDArray.cc
--- a/liboctave/fCNDArray.cc
+++ b/liboctave/fCNDArray.cc
@@ -490,6 +490,20 @@
 }
 
 // FIXME -- this is not quite the right thing.
+
+bool
+FloatComplexNDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      FloatComplex val = elem (i);
+      if (xisnan (val))
+       return true;
+    }
+  return false;
+}
 
 bool
 FloatComplexNDArray::any_element_is_inf_or_nan (void) const
diff --git a/liboctave/fCNDArray.h b/liboctave/fCNDArray.h
--- a/liboctave/fCNDArray.h
+++ b/liboctave/fCNDArray.h
@@ -64,6 +64,7 @@
 
   // FIXME -- this is not quite the right thing.
 
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
   bool all_integers (float& max_val, float& min_val) const;
diff --git a/liboctave/fMatrix.cc b/liboctave/fMatrix.cc
--- a/liboctave/fMatrix.cc
+++ b/liboctave/fMatrix.cc
@@ -2848,6 +2848,20 @@
   return false;
 }
 
+bool
+FloatMatrix::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisnan (val))
+       return true;
+    }
+
+  return false;
+}
 
 bool
 FloatMatrix::any_element_is_inf_or_nan (void) const
diff --git a/liboctave/fMatrix.h b/liboctave/fMatrix.h
--- a/liboctave/fMatrix.h
+++ b/liboctave/fMatrix.h
@@ -282,6 +282,7 @@
   boolMatrix map (bmapper fcn) const;
 
   bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool any_element_not_one_or_zero (void) const;
   bool all_elements_are_int_or_inf_or_nan (void) const;
diff --git a/liboctave/fNDArray.cc b/liboctave/fNDArray.cc
--- a/liboctave/fNDArray.cc
+++ b/liboctave/fNDArray.cc
@@ -514,6 +514,20 @@
   return false;
 }
 
+bool
+FloatNDArray::any_element_is_nan (void) const
+{
+  octave_idx_type nel = nelem ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      float val = elem (i);
+      if (xisnan (val))
+       return true;
+    }
+
+  return false;
+}
 
 bool
 FloatNDArray::any_element_is_inf_or_nan (void) const
diff --git a/liboctave/fNDArray.h b/liboctave/fNDArray.h
--- a/liboctave/fNDArray.h
+++ b/liboctave/fNDArray.h
@@ -67,6 +67,7 @@
   boolNDArray operator ! (void) const;
 
   bool any_element_is_negative (bool = false) const;
+  bool any_element_is_nan (void) 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;
diff --git a/liboctave/lo-mappers.h b/liboctave/lo-mappers.h
--- a/liboctave/lo-mappers.h
+++ b/liboctave/lo-mappers.h
@@ -41,6 +41,10 @@
 extern OCTAVE_API double xlog2 (double x, int& exp);
 extern OCTAVE_API Complex xlog2 (const Complex& x, int& exp);
 extern OCTAVE_API double xexp2 (double x);
+
+// These are used by the BOOL_OP macros in mx-op-defs.h.
+inline bool xisnan (bool) { return false; }
+inline bool xisnan (char) { return false; }
 
 extern OCTAVE_API bool xisnan (double x);
 extern OCTAVE_API bool xfinite (double x);
diff --git a/liboctave/mx-op-defs.h b/liboctave/mx-op-defs.h
--- a/liboctave/mx-op-defs.h
+++ b/liboctave/mx-op-defs.h
@@ -228,9 +228,21 @@
       { \
         r.resize (nr, nc); \
  \
-        for (int j = 0; j < nc; j++) \
-          for (int i = 0; i < nr; i++) \
-           r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \
+       if (xisnan (s)) \
+         gripe_nan_to_logical_conversion (); \
+       else \
+         { \
+ \
+           for (int j = 0; j < nc; j++) \
+             for (int i = 0; i < nr; i++) \
+               if (xisnan (m.elem(i, j))) \
+                 { \
+                   gripe_nan_to_logical_conversion (); \
+                   return r; \
+                 } \
+               else \
+                 r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); 
\
+           } \
       } \
  \
     return r; \
@@ -331,9 +343,20 @@
       { \
         r.resize (nr, nc); \
  \
-        for (int j = 0; j < nc; j++) \
-          for (int i = 0; i < nr; i++) \
-           r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \
+       if (xisnan (s)) \
+         gripe_nan_to_logical_conversion (); \
+       else \
+         { \
+           for (int j = 0; j < nc; j++) \
+             for (int i = 0; i < nr; i++) \
+               if (xisnan (m.elem(i, j))) \
+                 { \
+                   gripe_nan_to_logical_conversion (); \
+                   return r; \
+                 } \
+               else \
+                 r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); 
\
+         } \
       } \
  \
     return r; \
@@ -456,8 +479,14 @@
  \
            for (int j = 0; j < m1_nc; j++) \
              for (int i = 0; i < m1_nr; i++) \
-               r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \
-                                OP (m2.elem(i, j) != RHS_ZERO); \
+               if (xisnan (m1.elem(i, j)) || xisnan (m2.elem(i, j))) \
+                 { \
+                   gripe_nan_to_logical_conversion (); \
+                   return r; \
+                 } \
+               else \
+                 r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \
+                   OP (m2.elem(i, j) != RHS_ZERO); \
          } \
       } \
     else \
@@ -605,8 +634,19 @@
       { \
         r.resize (m.dims ()); \
  \
-        for (int i = 0; i < len; i++) \
-         r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \
+       if (xisnan (s)) \
+         gripe_nan_to_logical_conversion (); \
+       else \
+         { \
+           for (int i = 0; i < len; i++) \
+             if (xisnan (m.elem(i))) \
+               { \
+                 gripe_nan_to_logical_conversion (); \
+                 return r; \
+               } \
+             else \
+               r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \
+         } \
       } \
  \
     return r; \
@@ -748,8 +788,19 @@
       { \
         r.resize (m.dims ()); \
  \
-        for (int i = 0; i < len; i++) \
-           r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \
+       if (xisnan (s)) \
+         gripe_nan_to_logical_conversion (); \
+       else \
+         { \
+           for (int i = 0; i < len; i++) \
+             if (xisnan (m.elem(i))) \
+               { \
+                 gripe_nan_to_logical_conversion (); \
+                 return r; \
+               } \
+             else \
+               r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \
+           } \
       } \
  \
     return r; \
@@ -863,7 +914,13 @@
            r.resize (m1_dims); \
  \
            for (int i = 0; i < m1.length (); i++) \
-             r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); 
\
+             if (xisnan (m1.elem(i)) || xisnan (m2.elem(i))) \
+               { \
+                 gripe_nan_to_logical_conversion (); \
+                 return r; \
+               } \
+             else \
+               r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != 
RHS_ZERO); \
          } \
       } \
     else \
diff --git a/liboctave/oct-inttypes.h b/liboctave/oct-inttypes.h
--- a/liboctave/oct-inttypes.h
+++ b/liboctave/oct-inttypes.h
@@ -408,6 +408,13 @@
 };
 
 template <class T>
+bool
+xisnan (const octave_int<T>&)
+{
+  return false;
+}
+
+template <class T>
 octave_int<T>
 pow (const octave_int<T>& a, const octave_int<T>& b)
 {
diff --git a/scripts/general/logical.m b/scripts/general/logical.m
--- a/scripts/general/logical.m
+++ b/scripts/general/logical.m
@@ -42,7 +42,11 @@
     elseif (isempty (x))
       y = zeros (size (x), "logical");
     elseif (isnumeric (x))
-      y = x != 0;
+      if (any (isnan (x(:))))
+       error ("invalid conversion from NaN to logical");
+      else
+       y = x != 0;
+      endif
     else
       error ("logical not defined for type `%s'", typeinfo (x));
     endif
@@ -59,4 +63,6 @@
 %!assert (logical (-13), true);
 %!assert (logical (int8 (13)), true);
 %!assert (logical (int8 (-13)), true);
-%!assert (logical ([-1, 0, 1, NaN, Inf]), [-1, 0, 1, NaN, Inf] != 0);
+%!assert (logical ([-1, 0, 1, Inf]), [-1, 0, 1, Inf] != 0);
+%!error (logical ([-1, 0, 1, NaN, Inf]))
+%!error (logical (NaN))
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2008-07-11  John W. Eaton  <address@hidden>
+
+       * ov-float.h, ov-flt-re-mat.cc, ov-range.h, ov-re-mat.h,
+       ov-re-sparse.cc, ov-scalar.h: Check for NaN in bool_value and
+       bool_array_value member functions to bool.
+
+       * ops.h (DEFSCALARBOOLOP_OP): New macro.
+       * OPERATORS/op-s-s.cc, OPERATORS/op-fs-fs.cc: Use it to define
+       el_and and el_or ops.
+
 2008-07-10  David Bateman  <address@hidden>
 
        * DLD-FUNCTIONS/lookup.cc (assign): Delete.
diff --git a/src/OPERATORS/op-fs-fs.cc b/src/OPERATORS/op-fs-fs.cc
--- a/src/OPERATORS/op-fs-fs.cc
+++ b/src/OPERATORS/op-fs-fs.cc
@@ -114,8 +114,8 @@
   return octave_value (v2.float_value () / d);
 }
 
-DEFBINOP_OP (el_and, float_scalar, float_scalar, &&)
-DEFBINOP_OP (el_or, float_scalar, float_scalar, ||)
+DEFSCALARBOOLOP_OP (el_and, float_scalar, float_scalar, &&)
+DEFSCALARBOOLOP_OP (el_or, float_scalar, float_scalar, ||)
 
 DEFNDCATOP_FN (fs_fs, float_scalar, float_scalar, float_array, float_array, 
concat)
 DEFNDCATOP_FN (s_fs, scalar, float_scalar, float_array, float_array, concat)
diff --git a/src/OPERATORS/op-s-s.cc b/src/OPERATORS/op-s-s.cc
--- a/src/OPERATORS/op-s-s.cc
+++ b/src/OPERATORS/op-s-s.cc
@@ -115,8 +115,8 @@
   return octave_value (v2.double_value () / d);
 }
 
-DEFBINOP_OP (el_and, scalar, scalar, &&)
-DEFBINOP_OP (el_or, scalar, scalar, ||)
+DEFSCALARBOOLOP_OP (el_and, scalar, scalar, &&)
+DEFSCALARBOOLOP_OP (el_or, scalar, scalar, ||)
 
 DEFNDCATOP_FN (s_s, scalar, scalar, array, array, concat)
 
diff --git a/src/ops.h b/src/ops.h
--- a/src/ops.h
+++ b/src/ops.h
@@ -293,6 +293,20 @@
       (v1.t1 ## _value () op v2.t2 ## _value ()); \
   }
 
+#define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    if (xisnan (v1.t1 ## _value ()) || xisnan (v2.t2 ## _value ())) \
+      { \
+        error ("invalid conversion from NaN to logical"); \
+        return octave_value (); \
+      } \
+    else \
+      return octave_value \
+        (v1.t1 ## _value () op v2.t2 ## _value ()); \
+  }
+
 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
   BINOPDECL (name, a1, a2) \
   { \
diff --git a/src/ov-float.h b/src/ov-float.h
--- a/src/ov-float.h
+++ b/src/ov-float.h
@@ -191,7 +191,9 @@
 
   bool bool_value (bool warn = false) const
   {
-    if (warn && scalar != 0 && scalar != 1)
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
       gripe_logical_conversion ();
 
     return scalar;
@@ -199,7 +201,9 @@
 
   boolNDArray bool_array_value (bool warn = false) const
   {
-    if (warn && scalar != 0 && scalar != 1)
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
       gripe_logical_conversion ();
 
     return boolNDArray (dim_vector (1, 1), scalar);
diff --git a/src/ov-flt-re-mat.cc b/src/ov-flt-re-mat.cc
--- a/src/ov-flt-re-mat.cc
+++ b/src/ov-flt-re-mat.cc
@@ -218,7 +218,9 @@
 boolNDArray
 octave_float_matrix::bool_array_value (bool warn) const
 {
-  if (warn && matrix.any_element_not_one_or_zero ())
+  if (matrix.any_element_is_nan ())
+    error ("invalid conversion from NaN to logical");
+  else if (warn && matrix.any_element_not_one_or_zero ())
     gripe_logical_conversion ();
 
   return boolNDArray (matrix);
diff --git a/src/ov-range.h b/src/ov-range.h
--- a/src/ov-range.h
+++ b/src/ov-range.h
@@ -227,7 +227,9 @@
   {
     Matrix m = range.matrix_value ();
 
-    if (warn && m.any_element_not_one_or_zero ())
+    if (m.any_element_is_nan ())
+      error ("invalid conversion from NaN to logical");
+    else if (warn && m.any_element_not_one_or_zero ())
       gripe_logical_conversion ();
 
     return boolNDArray (m);
diff --git a/src/ov-re-mat.cc b/src/ov-re-mat.cc
--- a/src/ov-re-mat.cc
+++ b/src/ov-re-mat.cc
@@ -224,7 +224,9 @@
 boolNDArray
 octave_matrix::bool_array_value (bool warn) const
 {
-  if (warn && matrix.any_element_not_one_or_zero ())
+  if (matrix.any_element_is_nan ())
+    error ("invalid conversion from NaN to logical");
+  else if (warn && matrix.any_element_not_one_or_zero ())
     gripe_logical_conversion ();
 
   return boolNDArray (matrix);
diff --git a/src/ov-re-sparse.cc b/src/ov-re-sparse.cc
--- a/src/ov-re-sparse.cc
+++ b/src/ov-re-sparse.cc
@@ -150,7 +150,9 @@
 {
   NDArray m = matrix.matrix_value ();
 
-  if (warn && m.any_element_not_one_or_zero ())
+  if (m.any_element_is_nan ())
+    error ("invalid conversion from NaN to logical");
+  else if (warn && m.any_element_not_one_or_zero ())
     gripe_logical_conversion ();
 
   return boolNDArray (m);
diff --git a/src/ov-scalar.h b/src/ov-scalar.h
--- a/src/ov-scalar.h
+++ b/src/ov-scalar.h
@@ -192,7 +192,9 @@
 
   bool bool_value (bool warn = false) const
   {
-    if (warn && scalar != 0 && scalar != 1)
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
       gripe_logical_conversion ();
 
     return scalar;
@@ -200,7 +202,9 @@
 
   boolNDArray bool_array_value (bool warn = false) const
   {
-    if (warn && scalar != 0 && scalar != 1)
+    if (xisnan (scalar))
+      error ("invalid conversion from NaN to logical");
+    else if (warn && scalar != 0 && scalar != 1)
       gripe_logical_conversion ();
 
     return boolNDArray (dim_vector (1, 1), scalar);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]