changeset 8381:ad896677a2e2

implement binary saving of diag & perm matrices
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 08 Dec 2008 12:31:57 +0100
parents dbe67764e628
children 9b20a4847056
files liboctave/byte-swap.h src/ChangeLog src/ov-cx-diag.cc src/ov-cx-diag.h src/ov-flt-cx-diag.cc src/ov-flt-cx-diag.h src/ov-flt-re-diag.cc src/ov-flt-re-diag.h src/ov-perm.cc src/ov-perm.h src/ov-re-diag.cc src/ov-re-diag.h
diffstat 12 files changed, 336 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/byte-swap.h	Sun Dec 07 10:29:34 2008 +0100
+++ b/liboctave/byte-swap.h	Mon Dec 08 12:31:57 2008 +0100
@@ -40,7 +40,7 @@
 void
 swap_bytes (volatile void *ptr)
 {
-  for (size_t i = 0; i < n/2; i++)
+  for (int i = 0; i < n/2; i++)
     swap_bytes (ptr, i, n-1-i);
 }
 
--- a/src/ChangeLog	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ChangeLog	Mon Dec 08 12:31:57 2008 +0100
@@ -1,3 +1,21 @@
+2008-12-08  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-re-diag.cc (octave_diag_matrix::save_binary,
+	octave_diag_matrix::load_binary): New methods.
+	* ov-re-diag.h: Declare them.
+	* ov-flt-re-diag.cc (octave_float_diag_matrix::save_binary,
+	octave_float_diag_matrix::load_binary): New methods.
+	* ov-flt-re-diag.h: Declare them.
+	* ov-cx-diag.cc (octave_complex_diag_matrix::save_binary,
+	octave_complex_diag_matrix::load_binary): New methods.
+	* ov-cx-diag.h: Declare them.
+	* ov-flt-cx-diag.cc (octave_float_complex_diag_matrix::save_binary,
+	octave_float_complex_diag_matrix::load_binary): New methods.
+	* ov-flt-cx-diag.h: Declare them.
+	* ov-perm.cc (octave_perm_matrix::save_binary,
+	octave_perm_matrix::load_binary): New methods.
+	* ov-perm.h: Declare them.
+
 2008-12-06  Jaroslav Hajek  <highegg@gmail.com>
 
 	* ov-fcn-handle.cc (octave_fcn_handle::load_binary): Call istream::get
--- a/src/ov-cx-diag.cc	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-cx-diag.cc	Mon Dec 08 12:31:57 2008 +0100
@@ -24,12 +24,15 @@
 #include <config.h>
 #endif
 
+#include "byte-swap.h"
+
 #include "ov-cx-diag.h"
 #include "ov-flt-cx-diag.h"
 #include "ov-re-diag.h"
 #include "ov-base-diag.cc"
 #include "ov-complex.h"
 #include "ov-cx-mat.h"
+#include "ls-utils.h"
 
 template class octave_base_diag<ComplexDiagMatrix, ComplexMatrix>;
 
@@ -156,3 +159,64 @@
   return ::imag (matrix);
 }
 
+bool 
+octave_complex_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  ComplexMatrix m = ComplexMatrix (matrix.diag ());
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (matrix.length () > 4096) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const Complex *mtmp = m.data ();
+  write_doubles (os, reinterpret_cast<const double *> (mtmp), st, 2 * m.numel ());
+
+  return true;
+}
+
+bool 
+octave_complex_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  ComplexDiagMatrix m (r, c);
+  Complex *im = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_doubles (is, reinterpret_cast<double *> (im),
+                static_cast<save_type> (tmp), 2 * len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
--- a/src/ov-cx-diag.h	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-cx-diag.h	Mon Dec 08 12:31:57 2008 +0100
@@ -73,6 +73,11 @@
 
   FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
 
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
   octave_value abs (void) const;
   octave_value conj (void) const;
   octave_value imag (void) const;
--- a/src/ov-flt-cx-diag.cc	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-flt-cx-diag.cc	Mon Dec 08 12:31:57 2008 +0100
@@ -24,11 +24,14 @@
 #include <config.h>
 #endif
 
+#include "byte-swap.h"
+
 #include "ov-flt-cx-diag.h"
 #include "ov-base-diag.cc"
 #include "ov-flt-re-diag.h"
 #include "ov-flt-complex.h"
 #include "ov-flt-cx-mat.h"
+#include "ls-utils.h"
 
 template class octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix>;
 
@@ -139,3 +142,55 @@
 {
   return ::imag (matrix);
 }
+
+bool 
+octave_float_complex_diag_matrix::save_binary (std::ostream& os, 
+                                               bool& save_as_floats)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  FloatComplexMatrix m = FloatComplexMatrix (matrix.diag ());
+  save_type st = LS_FLOAT;
+  if (matrix.length () > 4096) // FIXME -- make this configurable.
+    {
+      float max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const FloatComplex *mtmp = m.data ();
+  write_floats (os, reinterpret_cast<const float *> (mtmp), st, 2 * m.numel ());
+
+  return true;
+}
+
+bool 
+octave_float_complex_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  FloatComplexDiagMatrix m (r, c);
+  FloatComplex *re = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_floats (is, reinterpret_cast<float *> (re), 
+               static_cast<save_type> (tmp), 2 * len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
--- a/src/ov-flt-cx-diag.h	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-flt-cx-diag.h	Mon Dec 08 12:31:57 2008 +0100
@@ -71,6 +71,11 @@
 
   FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
 
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
   octave_value abs (void) const;
   octave_value conj (void) const;
   octave_value imag (void) const;
--- a/src/ov-flt-re-diag.cc	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-flt-re-diag.cc	Mon Dec 08 12:31:57 2008 +0100
@@ -24,10 +24,13 @@
 #include <config.h>
 #endif
 
+#include "byte-swap.h"
+
 #include "ov-flt-re-diag.h"
 #include "ov-base-diag.cc"
 #include "ov-float.h"
 #include "ov-flt-re-mat.h"
+#include "ls-utils.h"
 
 template class octave_base_diag<FloatDiagMatrix, FloatMatrix>;
 
@@ -110,3 +113,53 @@
 {
   return DiagMatrix (matrix.rows (), matrix.cols ());
 }
+
+bool 
+octave_float_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  FloatMatrix m = FloatMatrix (matrix.diag ());
+  save_type st = LS_FLOAT;
+  if (matrix.length () > 8192) // FIXME -- make this configurable.
+    {
+      float max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const float *mtmp = m.data ();
+  write_floats (os, mtmp, st, m.numel ());
+
+  return true;
+}
+
+bool 
+octave_float_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  FloatDiagMatrix m (r, c);
+  float *re = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_floats (is, re, static_cast<save_type> (tmp), len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
--- a/src/ov-flt-re-diag.h	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-flt-re-diag.h	Mon Dec 08 12:31:57 2008 +0100
@@ -71,6 +71,11 @@
 
   FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
 
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
   octave_value abs (void) const;
   octave_value conj (void) const;
   octave_value imag (void) const;
--- a/src/ov-perm.cc	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-perm.cc	Mon Dec 08 12:31:57 2008 +0100
@@ -24,6 +24,8 @@
 #include <config.h>
 #endif
 
+#include "byte-swap.h"
+
 #include "ov-perm.h"
 #include "ov-flt-perm.h"
 #include "ov-re-mat.h"
@@ -294,9 +296,62 @@
   return success;
 }
 
+bool 
+octave_perm_matrix::save_binary (std::ostream& os, bool&)
+{
+
+  int32_t size = matrix.rows ();
+  bool colp = matrix.is_col_perm ();
+  os.write (reinterpret_cast<char *> (&size), 4);
+  os.write (reinterpret_cast<char *> (&colp), 1);
+  os.write (reinterpret_cast<const char *> (matrix.data ()), matrix.byte_size());
+
+  return true;
+}
+
+bool
+octave_perm_matrix::load_binary (std::istream& is, bool swap,
+                                 oct_mach_info::float_format )
+{
+  int32_t size;
+  bool colp;
+  if (! (is.read (reinterpret_cast<char *> (&size), 4)
+         && is.read (reinterpret_cast<char *> (&colp), 1)))
+    return false;
+
+  MArray<octave_idx_type> m (size);
+
+  if (! is.read (reinterpret_cast<char *> (m.fortran_vec ()), m.byte_size ()))
+    return false;
+
+  if (swap)
+    {
+      int nel = m.numel ();
+      for (int i = 0; i < nel; i++) 
+	switch (sizeof (octave_idx_type))
+	  {
+	  case 8:
+	    swap_bytes<8> (&m(i));
+	    break;
+	  case 4:
+	    swap_bytes<4> (&m(i));
+	    break;
+	  case 2:
+	    swap_bytes<2> (&m(i));
+	    break;
+	  case 1:
+	  default:
+	    break;
+	  }
+    }
+
+  matrix = PermMatrix (m, colp);
+  return true;
+}
+
 void
 octave_perm_matrix::print_raw (std::ostream& os,
-			  bool pr_as_read_syntax) const
+                               bool pr_as_read_syntax) const
 {
   return to_dense ().print_raw (os, pr_as_read_syntax);
 }
--- a/src/ov-perm.h	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-perm.h	Mon Dec 08 12:31:57 2008 +0100
@@ -185,6 +185,11 @@
 
   bool load_ascii (std::istream& is);
 
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
   int write (octave_stream& os, int block_size,
 	     oct_data_conv::data_type output_type, int skip,
 	     oct_mach_info::float_format flt_fmt) const;
--- a/src/ov-re-diag.cc	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-re-diag.cc	Mon Dec 08 12:31:57 2008 +0100
@@ -24,11 +24,14 @@
 #include <config.h>
 #endif
 
+#include "byte-swap.h"
+
 #include "ov-re-diag.h"
 #include "ov-flt-re-diag.h"
 #include "ov-base-diag.cc"
 #include "ov-scalar.h"
 #include "ov-re-mat.h"
+#include "ls-utils.h"
 
 template class octave_base_diag<DiagMatrix, Matrix>;
 
@@ -125,3 +128,64 @@
 {
   return DiagMatrix (matrix.rows (), matrix.cols ());
 }
+
+bool 
+octave_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
+{
+
+  int32_t r = matrix.rows (), c = matrix.cols ();
+  os.write (reinterpret_cast<char *> (&r), 4);
+  os.write (reinterpret_cast<char *> (&c), 4);
+
+  Matrix m = Matrix (matrix.diag ());
+  save_type st = LS_DOUBLE;
+  if (save_as_floats)
+    {
+      if (m.too_large_for_float ())
+	{
+	  warning ("save: some values too large to save as floats --");
+	  warning ("save: saving as doubles instead");
+	}
+      else
+	st = LS_FLOAT;
+    }
+  else if (matrix.length () > 8192) // FIXME -- make this configurable.
+    {
+      double max_val, min_val;
+      if (m.all_integers (max_val, min_val))
+	st = get_save_type (max_val, min_val);
+    }
+
+  const double *mtmp = m.data ();
+  write_doubles (os, mtmp, st, m.numel ());
+
+  return true;
+}
+
+bool 
+octave_diag_matrix::load_binary (std::istream& is, bool swap,
+				 oct_mach_info::float_format fmt)
+{
+  int32_t r, c;
+  char tmp;
+  if (! (is.read (reinterpret_cast<char *> (&r), 4)
+         && is.read (reinterpret_cast<char *> (&c), 4)
+         && is.read (reinterpret_cast<char *> (&tmp), 1)))
+    return false;
+  if (swap)
+    {
+      swap_bytes<4> (&r);
+      swap_bytes<4> (&c);
+    }
+
+  DiagMatrix m (r, c);
+  double *re = m.fortran_vec ();
+  octave_idx_type len = m.length ();
+  read_doubles (is, re, static_cast<save_type> (tmp), len, swap, fmt);
+  if (error_state || ! is)
+    return false;
+  matrix = m;
+
+  return true;
+}
+
--- a/src/ov-re-diag.h	Sun Dec 07 10:29:34 2008 +0100
+++ b/src/ov-re-diag.h	Mon Dec 08 12:31:57 2008 +0100
@@ -73,6 +73,11 @@
 
   FloatComplexDiagMatrix float_complex_diag_matrix_value (bool = false) const;
 
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
   octave_value abs (void) const;
   octave_value conj (void) const;
   octave_value imag (void) const;