changeset 7892:7ca2735d74c2

simplify & cleanup octave_value::XXX_vector_value functions
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 26 May 2008 14:01:55 +0200
parents 0280a546622c
children eb9ccb44ea41
files src/ChangeLog src/DLD-FUNCTIONS/fsolve.cc src/ov.cc
diffstat 3 files changed, 140 insertions(+), 463 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Jun 16 10:09:15 2008 +0200
+++ b/src/ChangeLog	Mon May 26 14:01:55 2008 +0200
@@ -1,3 +1,17 @@
+2008-06-20  Jaroslav Hajek <highegg@gmail.com>
+
+	* ov.cc (make_vector_dims): New function.
+	(vector_value, complex_vector_value, float_vector_value,
+	float_complex_vector_value): Query N-d array values and simplify,
+	avoid copying.
+	(column_vector_value, complex_column_vector_value,
+	float_column_vector_value, float_complex_column_vector_value,
+	row_vector_value, complex_row_vector_value,
+	float_row_vector_value, float_complex_row_vector_value): 
+	Simplify to trivial wrappers.
+	(int_vector_value): Avoid conversions if integer type, query N-d array
+	value, simplify.
+
 2008-06-17  John W. Eaton  <jwe@octave.org>
 
 	* toplev.h, toplev.cc (class octave_call_stack):
@@ -872,6 +886,14 @@
 	* ov-cell.cc (Fcellstr): For compatibility with Matlab, return {''}
 	when given ''.
 
+2008-05-26  Jaroslav Hajek <highegg@gmail.com>
+
+	* DLD-FUNCTIONS/fsolve.cc (fsolve_user_function,
+	fsolve_user_jacobian): Reshape argument to original dims before
+	passing. 
+	(Ffsolve): Save original dimensions of the starting guess and reshape
+	on return. Fix tests.
+
 2008-05-21  David Bateman  <dbateman@free.fr>
 
 	* DLD-FUNCTIONS/quad.cc (quad_float_user_function): New function.
--- a/src/DLD-FUNCTIONS/fsolve.cc	Mon Jun 16 10:09:15 2008 +0200
+++ b/src/DLD-FUNCTIONS/fsolve.cc	Mon May 26 14:01:55 2008 +0200
@@ -31,6 +31,7 @@
 #include <iostream>
 #include <sstream>
 
+#include "dNDArray.h"
 #include "NLEqn.h"
 
 #include "defun-dld.h"
@@ -52,6 +53,9 @@
 // Global pointer for optional user defined jacobian function.
 static octave_function *fsolve_jac;
 
+// Original dimensions of X0.
+static dim_vector x_dims;
+
 // Have we warned about imaginary values returned from user function?
 static bool warned_fcn_imaginary = false;
 static bool warned_jac_imaginary = false;
@@ -110,9 +114,7 @@
 
   if (n > 1)
     {
-      Matrix m (n, 1);
-      for (octave_idx_type i = 0; i < n; i++)
-	m (i, 0) = x (i);
+      NDArray m (ArrayN<double> (x, x_dims));
       octave_value vars (m);
       args(0) = vars;
     }
@@ -135,7 +137,7 @@
 	      warned_fcn_imaginary = true;
 	    }
 
-	  retval = ColumnVector (tmp(0).vector_value ());
+	  retval = ColumnVector (tmp(0).vector_value (false, true));
 
 	  if (error_state || retval.length () <= 0)
 	    gripe_user_supplied_eval ("fsolve");
@@ -161,9 +163,7 @@
 
   if (n > 1)
     {
-      Matrix m (n, 1);
-      for (octave_idx_type i = 0; i < n; i++)
-	m(i,0) = x(i);
+      NDArray m (ArrayN<double> (x, x_dims));
       octave_value vars (m);
       args(0) = vars;
     }
@@ -399,7 +399,9 @@
       if (error_state || ! fsolve_fcn)
 	FSOLVE_ABORT ();
 
-      ColumnVector x (args(1).vector_value ());
+      NDArray xa = args(1).array_value ();
+      x_dims = xa.dims ();
+      ColumnVector x (xa);
 
       if (error_state)
 	FSOLVE_ABORT1 ("expecting vector as second argument");
@@ -429,7 +431,7 @@
 	{
 	  retval(2) = static_cast<double> (hybrd_info_to_fsolve_info (info));
 	  retval(1) = nleqn.function_value ();
-	  retval(0) = soln;
+	  retval(0) = NDArray (ArrayN<double> (soln.reshape (x_dims)));
 
 	  if (! nleqn.solution_ok () && nargout < 2)
 	    {
@@ -460,7 +462,7 @@
 %! 2.395931;
 %! 2.005014 ];
 %! tol = 1.0e-5;
-%! [x, fval, info] = fsolve ("f", [ 0.5, 2.0, 2.5 ]);
+%! [x, fval, info] = fsolve ("f", [ 0.5; 2.0; 2.5 ]);
 %! info_bad = (info != 1);
 %! solution_bad = sum (abs (x - x_opt) > tol);
 %! value_bad = sum (abs (fval) > tol);
@@ -492,10 +494,7 @@
 %!  retval(3) = x^4 - 4*y^2 + 6*z - 8*w - 20;
 %!  retval(4) = x^2 + 2*y^3 + z - w - 4;
 %!test
-%! x_opt = [ -0.767297326653401;
-%! 0.590671081117440;
-%! 1.47190018629642;
-%! -1.52719341133957 ];
+%! x_opt = [ -0.767297326653401, 0.590671081117440, 1.47190018629642, -1.52719341133957 ];
 %! tol = 1.0e-5;
 %! [x, fval, info] = fsolve ("f", [-1, 1, 2, -1]);
 %! info_bad = (info != 1);
--- a/src/ov.cc	Mon Jun 16 10:09:15 2008 +0200
+++ b/src/ov.cc	Mon May 26 14:01:55 2008 +0200
@@ -1281,173 +1281,69 @@
   return rep->list_value ();
 }
 
-ColumnVector
-octave_value::column_vector_value (bool force_string_conv,
-				   bool /* frc_vec_conv */) const
+static dim_vector
+make_vector_dims (const dim_vector& dv, bool force_vector_conversion,
+                  const std::string& my_type, const std::string& wanted_type)
 {
-  ColumnVector retval;
-
-  Matrix m = matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	retval (i) = m (i, 0);
-    }
-  else
+  dim_vector retval (dv);
+  retval.chop_trailing_singletons ();
+  octave_idx_type nel = dv.numel ();
+
+  if (retval.length () > 2 || (retval(0) != 1 && retval(1) != 1))
     {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real column vector");
-    }
-
-  return retval;
-}
-
-ComplexColumnVector
-octave_value::complex_column_vector_value (bool force_string_conv,
-					   bool /* frc_vec_conv */) const
-{
-  ComplexColumnVector retval;
-
-  ComplexMatrix m = complex_matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	retval (i) = m (i, 0);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "complex column vector");
+      if (!force_vector_conversion)
+        gripe_implicit_conversion ("Octave:array-as-vector",
+                                   my_type.c_str (), wanted_type.c_str ());
+      retval = dim_vector (nel);
     }
 
   return retval;
 }
 
+ColumnVector
+octave_value::column_vector_value (bool force_string_conv,
+                                   bool frc_vec_conv) const
+{
+  return ColumnVector (vector_value (force_string_conv, 
+                                     frc_vec_conv));
+}
+
+ComplexColumnVector
+octave_value::complex_column_vector_value (bool force_string_conv,
+                                           bool frc_vec_conv) const
+{
+  return ComplexColumnVector (complex_vector_value (force_string_conv, 
+                                                    frc_vec_conv));
+}
+
 RowVector
 octave_value::row_vector_value (bool force_string_conv,
-				bool /* frc_vec_conv */) const
+                                bool frc_vec_conv) const
 {
-  RowVector retval;
-
-  Matrix m = matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	retval (i) = m (0, i);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real row vector");
-    }
-
-  return retval;
+  return RowVector (vector_value (force_string_conv, 
+                                  frc_vec_conv));
 }
 
 ComplexRowVector
 octave_value::complex_row_vector_value (bool force_string_conv,
-					bool /* frc_vec_conv */) const
+                                        bool frc_vec_conv) const
 {
-  ComplexRowVector retval;
-
-  ComplexMatrix m = complex_matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	retval (i) = m (0, i);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "complex row vector");
-    }
-
-  return retval;
+  return ComplexRowVector (complex_vector_value (force_string_conv, 
+                                                 frc_vec_conv));
 }
 
-// Sloppy...
-
 Array<double>
 octave_value::vector_value (bool force_string_conv,
 			    bool force_vector_conversion) const
 {
-  Array<double> retval;
-
-  Matrix m = matrix_value (force_string_conv);
+  Array<double> retval = array_value (force_string_conv);
 
   if (error_state)
     return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	retval (i) = m (0, i);
-    }
-  else if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	retval (i) = m (i, 0);
-    }
-  else if (nr > 0 && nc > 0)
-    {
-      if (! force_vector_conversion)
-	gripe_implicit_conversion ("Octave:array-as-vector",
-				   type_name (), "real vector");
-
-      retval.resize (nr * nc);
-      octave_idx_type k = 0;
-      for (octave_idx_type j = 0; j < nc; j++)
-	for (octave_idx_type i = 0; i < nr; i++)
-	  {
-	    OCTAVE_QUIT;
-
-	    retval (k++) = m (i, j);
-	  }
-    }
   else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real vector");
-    }
-
-  return retval;
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "real vector"));
 }
 
 Array<int>
@@ -1456,364 +1352,124 @@
 {
   Array<int> retval;
 
-  Matrix m = matrix_value (force_string_conv);
+  if (is_integer_type ())
+    {
+      // query for the first type that is wide enough
+#if SIZEOF_INT == 2
+      retval = int16_array_value ();
+#elif SIZEOF_INT == 4
+      retval = int32_array_value ();
+#else
+      retval = int64_array_value ();
+#endif
+    }
+  else 
+    {
+      const NDArray a = array_value (force_string_conv);
+      if (! error_state)
+        {
+          if (require_int)
+            {
+              retval.resize (a.dims ());
+              for (octave_idx_type i = 0; i < a.numel (); i++)
+                {
+                  double ai = a.elem (i);
+                  int v = static_cast<int> (ai);
+                  if (ai == v)
+                    retval.xelem (i) = v;
+                  else
+                    {
+                      error ("conversion to integer value failed");
+                      break;
+                    }
+                }
+            }
+          else
+            retval = Array<int> (a);
+        }
+    }
+
 
   if (error_state)
     return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	{
-	  OCTAVE_QUIT;
-
-	  double d = m (0, i);
-
-	  if (require_int && D_NINT (d) != d)
-	    {
-	      error ("conversion to integer value failed");
-	      return retval;
-	    }
-
-	  retval (i) = static_cast<int> (d);
-	}
-    }
-  else if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	{
-	  OCTAVE_QUIT;
-
-	  double d = m (i, 0);
-
-	  if (require_int && D_NINT (d) != d)
-	    {
-	      error ("conversion to integer value failed");
-	      return retval;
-	    }
-
-	  retval (i) = static_cast<int> (d);
-	}
-    }
-  else if (nr > 0 && nc > 0)
-    {
-      if (! force_vector_conversion)
-	gripe_implicit_conversion ("Octave:array-as-vector",
-				   type_name (), "real vector");
-
-      retval.resize (nr * nc);
-      octave_idx_type k = 0;
-      for (octave_idx_type j = 0; j < nc; j++)
-	{
-	  for (octave_idx_type i = 0; i < nr; i++)
-	    {
-	      OCTAVE_QUIT;
-
-	      double d = m (i, j);
-
-	      if (require_int && D_NINT (d) != d)
-		{
-		  error ("conversion to integer value failed");
-		  return retval;
-		}
-
-	      retval (k++) = static_cast<int> (d);
-	    }
-	}
-    }
   else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real vector");
-    }
-
-  return retval;
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "integer vector"));
 }
 
 Array<Complex>
 octave_value::complex_vector_value (bool force_string_conv,
-				    bool force_vector_conversion) const
+                                    bool force_vector_conversion) const
 {
-  Array<Complex> retval;
-
-  ComplexMatrix m = complex_matrix_value (force_string_conv);
+  Array<Complex> retval = complex_array_value (force_string_conv);
 
   if (error_state)
     return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	{
-	  OCTAVE_QUIT;
-	  retval (i) = m (0, i);
-	}
-    }
-  else if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	{
-	  OCTAVE_QUIT;
-	  retval (i) = m (i, 0);
-	}
-    }
-  else if (nr > 0 && nc > 0)
-    {
-      if (! force_vector_conversion)
-	gripe_implicit_conversion ("Octave:array-as-vector",
-				   type_name (), "complex vector");
-
-      retval.resize (nr * nc);
-      octave_idx_type k = 0;
-      for (octave_idx_type j = 0; j < nc; j++)
-	for (octave_idx_type i = 0; i < nr; i++)
-	  {
-	    OCTAVE_QUIT;
-	    retval (k++) = m (i, j);
-	  }
-    }
   else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "complex vector");
-    }
-
-  return retval;
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "complex vector"));
 }
 
 FloatColumnVector
 octave_value::float_column_vector_value (bool force_string_conv,
-				   bool /* frc_vec_conv */) const
+                                         bool frc_vec_conv) const
 {
-  FloatColumnVector retval;
-
-  FloatMatrix m = float_matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	retval (i) = m (i, 0);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real column vector");
-    }
-
-  return retval;
+  return FloatColumnVector (float_vector_value (force_string_conv, 
+                                                frc_vec_conv));
 }
 
 FloatComplexColumnVector
 octave_value::float_complex_column_vector_value (bool force_string_conv,
-					   bool /* frc_vec_conv */) const
+                                                 bool frc_vec_conv) const
 {
-  FloatComplexColumnVector retval;
-
-  FloatComplexMatrix m = float_complex_matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	retval (i) = m (i, 0);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "complex column vector");
-    }
-
-  return retval;
+  return FloatComplexColumnVector (float_complex_vector_value (force_string_conv, 
+                                                               frc_vec_conv));
 }
 
 FloatRowVector
 octave_value::float_row_vector_value (bool force_string_conv,
-				bool /* frc_vec_conv */) const
+                                      bool frc_vec_conv) const
 {
-  FloatRowVector retval;
-
-  FloatMatrix m = float_matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	retval (i) = m (0, i);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real row vector");
-    }
-
-  return retval;
+  return FloatRowVector (float_vector_value (force_string_conv, 
+                                             frc_vec_conv));
 }
 
 FloatComplexRowVector
 octave_value::float_complex_row_vector_value (bool force_string_conv,
-					bool /* frc_vec_conv */) const
+                                              bool frc_vec_conv) const
 {
-  FloatComplexRowVector retval;
-
-  FloatComplexMatrix m = float_complex_matrix_value (force_string_conv);
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	retval (i) = m (0, i);
-    }
-  else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "complex row vector");
-    }
-
-  return retval;
+  return FloatComplexRowVector (float_complex_vector_value (force_string_conv, 
+                                                           frc_vec_conv));
 }
 
-// Sloppy...
-
 Array<float>
 octave_value::float_vector_value (bool force_string_conv,
-			    bool force_vector_conversion) const
+                                  bool force_vector_conversion) const
 {
-  Array<float> retval;
-
-  FloatMatrix m = float_matrix_value (force_string_conv);
+  Array<float> retval = float_array_value (force_string_conv);
 
   if (error_state)
     return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	retval (i) = m (0, i);
-    }
-  else if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	retval (i) = m (i, 0);
-    }
-  else if (nr > 0 && nc > 0)
-    {
-      if (! force_vector_conversion)
-	gripe_implicit_conversion ("Octave:array-as-vector",
-				   type_name (), "real vector");
-
-      retval.resize (nr * nc);
-      octave_idx_type k = 0;
-      for (octave_idx_type j = 0; j < nc; j++)
-	for (octave_idx_type i = 0; i < nr; i++)
-	  {
-	    OCTAVE_QUIT;
-
-	    retval (k++) = m (i, j);
-	  }
-    }
   else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "real vector");
-    }
-
-  return retval;
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "real vector"));
 }
 
 Array<FloatComplex>
 octave_value::float_complex_vector_value (bool force_string_conv,
-				    bool force_vector_conversion) const
+                                          bool force_vector_conversion) const
 {
-  Array<FloatComplex> retval;
-
-  FloatComplexMatrix m = float_complex_matrix_value (force_string_conv);
+  Array<FloatComplex> retval = float_complex_array_value (force_string_conv);
 
   if (error_state)
     return retval;
-
-  octave_idx_type nr = m.rows ();
-  octave_idx_type nc = m.columns ();
-
-  if (nr == 1)
-    {
-      retval.resize (nc);
-      for (octave_idx_type i = 0; i < nc; i++)
-	{
-	  OCTAVE_QUIT;
-	  retval (i) = m (0, i);
-	}
-    }
-  else if (nc == 1)
-    {
-      retval.resize (nr);
-      for (octave_idx_type i = 0; i < nr; i++)
-	{
-	  OCTAVE_QUIT;
-	  retval (i) = m (i, 0);
-	}
-    }
-  else if (nr > 0 && nc > 0)
-    {
-      if (! force_vector_conversion)
-	gripe_implicit_conversion ("Octave:array-as-vector",
-				   type_name (), "complex vector");
-
-      retval.resize (nr * nc);
-      octave_idx_type k = 0;
-      for (octave_idx_type j = 0; j < nc; j++)
-	for (octave_idx_type i = 0; i < nr; i++)
-	  {
-	    OCTAVE_QUIT;
-	    retval (k++) = m (i, j);
-	  }
-    }
   else
-    {
-      std::string tn = type_name ();
-      gripe_invalid_conversion (tn.c_str (), "complex vector");
-    }
-
-  return retval;
+    return retval.reshape (make_vector_dims (retval.dims (),
+                                             force_vector_conversion,
+                                             type_name (), "complex vector"));
 }
 
 int