changeset 4025:cfb762dc9259

[project @ 2002-08-09 06:32:15 by jwe]
author jwe
date Fri, 09 Aug 2002 06:32:16 +0000
parents 00d06e24cc89
children 8cb8eff3f44c
files liboctave/ChangeLog liboctave/lo-ieee.cc liboctave/lo-ieee.h liboctave/lo-mappers.cc liboctave/lo-mappers.h src/ChangeLog src/data.cc src/mappers.cc src/parse.y src/pr-output.cc
diffstat 10 files changed, 178 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Wed Aug 07 07:11:44 2002 +0000
+++ b/liboctave/ChangeLog	Fri Aug 09 06:32:16 2002 +0000
@@ -1,3 +1,14 @@
+2002-08-08  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* lo-ieee.cc (lo_ieee_is_NA): New function.
+	(lo_ieee_is_NaN_or_NA): New function.
+	(octave_NA): New global value.
+	(octave_ieee_init): Initialize it.
+	* lo-mappers.cc (octave_is_NA): New function.
+	(octave_is_NaN_or_NA): New function.
+	(xisnan): Return false if NaN looks like a missing value.
+	(xisnan (const Complex&)): Use xisnan here.
+
 2002-08-02  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* CMatrix.h (ComplexMatrix::all, ComplexMatrix::any,
--- a/liboctave/lo-ieee.cc	Wed Aug 07 07:11:44 2002 +0000
+++ b/liboctave/lo-ieee.cc	Fri Aug 09 06:32:16 2002 +0000
@@ -46,6 +46,7 @@
 #endif
 
 #include "lo-ieee.h"
+#include "mach-info.h"
 
 // Octave's idea of infinity.
 double octave_Inf;
@@ -53,6 +54,21 @@
 // Octave's idea of not a number.
 double octave_NaN;
 
+// Octave's idea of a missing value.
+double octave_NA;
+
+static int hw;
+static int lw;
+
+typedef union
+{
+  double value;
+  unsigned int word[2];
+} ieee_double;
+
+#define NA_HW 0x7ff00000
+#define NA_LW 1954
+
 void
 octave_ieee_init (void)
 {
@@ -90,6 +106,27 @@
   octave_NaN = octave_Inf / octave_Inf;
 #endif
 
+  // This is patterned after code in R.
+
+  oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
+
+  if (ff == oct_mach_info::ieee_big_endian)
+    {
+      hw = 0;
+      lw = 1;
+    }
+  else
+    {
+      hw = 1;
+      lw = 0;
+    }
+
+  ieee_double t;
+  t.word[hw] = NA_HW;
+  t.word[lw] = NA_LW;
+
+  octave_NA = t.value;
+
 #endif
 }
 
@@ -109,6 +146,20 @@
 
 #endif
 
+extern "C" int
+lo_ieee_is_NA (double x)
+{
+  ieee_double t;
+  t.value = x;
+  return (isnan (x) && t.word[lw] == NA_LW) ? 1 : 0;
+}
+
+extern "C" int
+lo_ieee_is_NaN_or_NA (double x)
+{
+  return isnan (x);
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/lo-ieee.h	Wed Aug 07 07:11:44 2002 +0000
+++ b/liboctave/lo-ieee.h	Fri Aug 09 06:32:16 2002 +0000
@@ -29,8 +29,14 @@
 // Octave's idea of not a number.
 extern double octave_NaN;
 
+// Octave's idea of a missing value.
+extern double octave_NA;
+
 extern void octave_ieee_init (void);
 
+extern "C" int lo_ieee_is_NA (double);
+extern "C" int lo_ieee_is_NaN_or_NA (double);
+
 #if defined (SCO)
 extern "C" int isnan (double);
 extern "C" int isinf (double);
--- a/liboctave/lo-mappers.cc	Wed Aug 07 07:11:44 2002 +0000
+++ b/liboctave/lo-mappers.cc	Fri Aug 09 06:32:16 2002 +0000
@@ -143,7 +143,7 @@
 xisnan (double x)
 {
 #if defined (HAVE_ISNAN)
-  return isnan (x) != 0;
+  return isnan (x) ? ! lo_ieee_is_NA (x) : false;
 #else
   return false;
 #endif
@@ -153,11 +153,11 @@
 xfinite (double x)
 {
 #if defined (HAVE_FINITE)
-  return finite (x) != 0;
-#elif defined (HAVE_ISINF) && defined (HAVE_ISNAN)
-  return (! isinf (x) && ! isnan (x));
+  return finite (x) != 0 && ! octave_is_NaN_or_NA (x);
+#elif defined (HAVE_ISINF)
+  return (! isinf (x) && ! octave_is_NaN_or_NA (x));
 #else
-  return true;
+  return ! octave_is_NaN_or_NA (x);
 #endif
 }
 
@@ -166,15 +166,29 @@
 {
 #if defined (HAVE_ISINF)
   return isinf (x);
-#elif defined (HAVE_FINITE) && defined (HAVE_ISNAN)
-  return (! (finite (x) || isnan (x)));
+#elif defined (HAVE_FINITE)
+  return (! (finite (x) || octave_is_NaN_or_NA (x)));
 #else
   return false;
 #endif
 }
 
+bool
+octave_is_NA (double x)
+{
+  return lo_ieee_is_NA (x);
+}
+
+bool
+octave_is_NaN_or_NA (double x)
+{
+  return lo_ieee_is_NaN_or_NA (x);
+}
+
 // (double, double) -> double mappers.
 
+// XXX FIXME XXX -- need to handle NA too?
+
 double
 xmin (double x, double y)
 {
@@ -288,17 +302,17 @@
 bool
 xisnan (const Complex& x)
 {
-#if defined (HAVE_ISNAN)
-  return (isnan (real (x)) || isnan (imag (x)));
-#else
-  return false;
-#endif
+  return (xisnan (real (x)) || xisnan (imag (x)));
 }
 
 bool
 xfinite (const Complex& x)
 {
-  return (xfinite (real (x)) && xfinite (imag (x)));
+  double rx = real (x);
+  double ix = imag (x);
+
+  return (xfinite (rx) && ! octave_is_NaN_or_NA (rx)
+	  && xfinite (ix) && ! octave_is_NaN_or_NA (ix));
 }
 
 bool
@@ -307,8 +321,22 @@
   return (xisinf (real (x)) || xisinf (imag (x)));
 }
 
+bool
+octave_is_NA (const Complex& x)
+{
+  return (octave_is_NA (real (x)) || octave_is_NA (imag (x)));
+}
+
+bool
+octave_is_NaN_or_NA (const Complex& x)
+{
+  return (octave_is_NaN_or_NA (real (x)) || octave_is_NaN_or_NA (imag (x)));
+}
+
 // (complex, complex) -> complex mappers.
 
+// XXX FIXME XXX -- need to handle NA too?
+
 Complex
 xmin (const Complex& x, const Complex& y)
 {
--- a/liboctave/lo-mappers.h	Wed Aug 07 07:11:44 2002 +0000
+++ b/liboctave/lo-mappers.h	Fri Aug 09 06:32:16 2002 +0000
@@ -39,6 +39,9 @@
 extern bool xfinite (double x);
 extern bool xisinf (double x);
 
+extern bool octave_is_NA (double x);
+extern bool octave_is_NaN_or_NA (double x);
+
 extern double xmin (double x, double y);
 extern double xmax (double x, double y);
 
--- a/src/ChangeLog	Wed Aug 07 07:11:44 2002 +0000
+++ b/src/ChangeLog	Fri Aug 09 06:32:16 2002 +0000
@@ -1,3 +1,18 @@
+2002-08-09  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* parse.y (switch_case): Make list of command optional.
+
+2002-08-08  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* pr-output.cc (pr_max_internal): Use octave_is_NaN_or_NA instead
+	of xisnan.
+	(pr_min_internal): Likewise.
+	(output_max_field_width): Likewise.
+	(output_precision): Likewise.
+	(pr_any_float): Handle NA.
+	* mappers.cc (Fisna, F_is_nan_or_na): New functions.
+	* data.cc (symbols_of_data): New constant, NA.
+
 2002-08-07  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* pt-binop.h (tree_binary_expression::is_binary_expression):
--- a/src/data.cc	Wed Aug 07 07:11:44 2002 +0000
+++ b/src/data.cc	Fri Aug 09 06:32:16 2002 +0000
@@ -1193,6 +1193,12 @@
   DEFCONST (J, Complex (0.0, 1.0),
     IMAGINARY_DOC_STRING);
 
+  DEFCONST (NA, octave_NA,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} NA\n\
+Missing value.\n\
+@end defvr");
+
   DEFCONST (NaN, octave_NaN,
     NAN_DOC_STRING);
 
--- a/src/mappers.cc	Wed Aug 07 07:11:44 2002 +0000
+++ b/src/mappers.cc	Fri Aug 09 06:32:16 2002 +0000
@@ -429,8 +429,8 @@
 \n\
 @example\n\
 @group\n\
-isinf ([13, Inf, NaN])\n\
-     @result{} [ 0, 1, 0 ]\n\
+isinf ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 1, 0, 0 ]\n\
 @end group\n\
 @end example\n\
 @end deftypefn");
@@ -447,6 +447,35 @@
 Return 1 for characters that are lower case letters.\n\
 @end deftypefn");
 
+  DEFUN_MAPPER (isna, 0, octave_is_NA, octave_is_NA, 0, 0, 0, 0.0, 0.0, 0,
+    "-*- texinfo -*-\n\
+@deftypefn {Mapping Function} {} isna (@var{x})\n\
+Return 1 for elements of @var{x} that are NA (missing) values and zero\n\
+otherwise. For example,\n\
+\n\
+@example\n\
+@group\n\
+is_NA ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 0, 1, 0 ]\n\
+@end group\n\
+@end example\n\
+@end deftypefn");
+
+  DEFUN_MAPPER (is_nan_or_na, 0, octave_is_NaN_or_NA,
+		octave_is_NaN_or_NA, 0, 0, 0, 0.0, 0.0, 0,
+    "-*- texinfo -*-\n\
+@deftypefn {Mapping Function} {} is_nan_or_na (@var{x})\n\
+Return 1 for elements of @var{x} that are NaN or NA (missing) values\n\
+and zero otherwise. For example,\n\
+\n\
+@example\n\
+@group\n\
+is_NAN_or_NA ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 0, 1, 1 ]\n\
+@end group\n\
+@end example\n\
+@end deftypefn");
+
   DEFUN_MAPPER (isnan, 0, xisnan, xisnan, 0, 0, 0, 0.0, 0.0, 0,
     "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} isnan (@var{x})\n\
@@ -455,8 +484,8 @@
 \n\
 @example\n\
 @group\n\
-isnan ([13, Inf, NaN])\n\
-     @result{} [ 0, 0, 1 ]\n\
+isnan ([13, Inf, NA, NaN])\n\
+     @result{} [ 0, 0, 0, 1 ]\n\
 @end group\n\
 @end example\n\
 @end deftypefn");
--- a/src/parse.y	Wed Aug 07 07:11:44 2002 +0000
+++ b/src/parse.y	Fri Aug 09 06:32:16 2002 +0000
@@ -998,7 +998,7 @@
 		  }
 		;
 
-switch_case	: CASE stash_comment opt_sep expression opt_sep list
+switch_case	: CASE stash_comment opt_sep expression opt_sep opt_list
 		  { $$ = make_switch_case ($4, $6, $2); }
 		;
 
--- a/src/pr-output.cc	Wed Aug 07 07:11:44 2002 +0000
+++ b/src/pr-output.cc	Fri Aug 09 06:32:16 2002 +0000
@@ -215,7 +215,7 @@
     for (int i = 0; i < nr; i++)
       {
 	double val = m(i,j);
-	if (xisinf (val) || xisnan (val))
+	if (xisinf (val) || octave_is_NaN_or_NA (val))
 	  continue;
 
 	if (val > result)
@@ -237,7 +237,7 @@
     for (int i = 0; i < nr; i++)
       {
 	double val = m(i,j);
-	if (xisinf (val) || xisnan (val))
+	if (xisinf (val) || octave_is_NaN_or_NA (val))
 	  continue;
 
 	if (val < result)
@@ -1138,6 +1138,13 @@
 	  else
 	    os << s;
 	}
+      else if (octave_is_NA (d))
+	{
+	  if (fw > 0)
+	    os << std::setw (fw) << "NA";
+	  else
+	    os << "NA";
+	}
       else if (xisnan (d))
 	{
 	  if (fw > 0)
@@ -2102,7 +2109,7 @@
 {
   double val;
   if (builtin_real_scalar_variable ("output_max_field_width", val)
-      && ! xisnan (val))
+      && ! octave_is_NaN_or_NA (val))
     {
       int ival = NINT (val);
       if (ival > 0 && ival == val)
@@ -2120,7 +2127,7 @@
 {
   double val;
   if (builtin_real_scalar_variable ("output_precision", val)
-      && ! xisnan (val))
+      && ! octave_is_NaN_or_NA (val))
     {
       int ival = NINT (val);
       if (ival >= 0 && ival == val)