diff src/data.cc @ 6953:4567a35e0777

[project @ 2007-10-04 02:53:11 by jwe]
author jwe
date Thu, 04 Oct 2007 02:54:00 +0000
parents 6bbf56a9718a
children 47f4f4e88166
line wrap: on
line diff
--- a/src/data.cc	Wed Oct 03 21:37:08 2007 +0000
+++ b/src/data.cc	Thu Oct 04 02:54:00 2007 +0000
@@ -34,18 +34,19 @@
 #include "str-vec.h"
 #include "quit.h"
 
+#include "Cell.h"
 #include "defun.h"
 #include "error.h"
 #include "gripes.h"
+#include "oct-map.h"
+#include "oct-obj.h"
 #include "ov.h"
 #include "ov-complex.h"
 #include "ov-cx-mat.h"
-#include "variables.h"
-#include "oct-obj.h"
+#include "parse.h"
+#include "pt-mat.h"
 #include "utils.h"
-#include "Cell.h"
-#include "oct-map.h"
-#include "pt-mat.h"
+#include "variables.h"
 
 #define ANY_ALL(FCN) \
  \
@@ -2614,74 +2615,141 @@
   return retval;
 }
 
+/*
+%!shared x
+%! x = [1, -3, 4, 5, -7];
+%!assert(norm(x,1), 20);
+%!assert(norm(x,2), 10);
+%!assert(norm(x,3), 8.24257059961711, -4*eps);
+%!assert(norm(x,Inf), 7);
+%!assert(norm(x,-Inf), 1);
+%!assert(norm(x,"inf"), 7);
+%!assert(norm(x,"fro"), 10);
+%!assert(norm(x), 10);
+%!assert(norm([1e200, 1]), 1e200);
+%!assert(norm([3+4i, 3-4i, sqrt(31)]), 9, -4*eps);
+%!shared m
+%! m = magic (4);
+%!assert(norm(m,1), 34);
+%!assert(norm(m,2), 34);
+%!assert(norm(m,Inf), 34);
+%!assert(norm(m,"inf"), 34);
+*/
+
 // Compute various norms of the vector X.
 
-DEFUN (__vnorm__, args, ,
+DEFUN (norm, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} __vnorm__ (@var{x}, @var{p})\n\
-Undocumented internal function.\n\
+@deftypefn {Function File} {} norm (@var{a}, @var{p})\n\
+Compute the p-norm of the matrix @var{a}.  If the second argument is\n\
+missing, @code{p = 2} is assumed.\n\
+\n\
+If @var{a} is a matrix:\n\
+\n\
+@table @asis\n\
+@item @var{p} = @code{1}\n\
+1-norm, the largest column sum of the absolute values of @var{a}.\n\
+\n\
+@item @var{p} = @code{2}\n\
+Largest singular value of @var{a}.\n\
+\n\
+@item @var{p} = @code{Inf}\n\
+@cindex infinity norm\n\
+Infinity norm, the largest row sum of the absolute values of @var{a}.\n\
+\n\
+@item @var{p} = @code{\"fro\"}\n\
+@cindex Frobenius norm\n\
+Frobenius norm of @var{a}, @code{sqrt (sum (diag (@var{a}' * @var{a})))}.\n\
+@end table\n\
+\n\
+If @var{a} is a vector or a scalar:\n\
+\n\
+@table @asis\n\
+@item @var{p} = @code{Inf}\n\
+@code{max (abs (@var{a}))}.\n\
+\n\
+@item @var{p} = @code{-Inf}\n\
+@code{min (abs (@var{a}))}.\n\
+\n\
+@item other\n\
+p-norm of @var{a}, @code{(sum (abs (@var{a}) .^ @var{p})) ^ (1/@var{p})}.\n\
+@end table\n\
+@seealso{cond, svd}\n\
 @end deftypefn")
 {
-  octave_value retval;
+  // Currently only handles vector norms for full double/complex
+  // vectors internally.  Other cases are handled by __norm__.m.
+
+  octave_value_list retval;
 
   int nargin = args.length ();
 
   if (nargin == 1 || nargin == 2)
     {
-      double p_val;
-
-      octave_value p_arg;
-
-      if (nargin == 1)
-	p_arg = 2;
-      else
-	p_arg = args(1);
-
-      if (p_arg.is_string ())
+      octave_value x_arg = args(0);
+
+      if (x_arg.is_empty ())
+	retval(0) = 0.0;
+      else if (x_arg.ndims () == 2)
 	{
-	  std::string p = args(1).string_value ();
-
-	  if (p == "inf")
-	    p_val = octave_Inf;
-	  else if (p == "fro")
-	    p_val = -1;
+	  if ((x_arg.rows () == 1 || x_arg.columns () == 1)
+	      && ! (x_arg.is_sparse_type () || x_arg.is_integer_type ()))
+	    {
+	      double p_val;
+
+	      octave_value p_arg;
+
+	      if (nargin == 1)
+		p_arg = 2;
+	      else
+		p_arg = args(1);
+
+	      if (p_arg.is_string ())
+		{
+		  std::string p = args(1).string_value ();
+
+		  if (p == "inf")
+		    p_val = octave_Inf;
+		  else if (p == "fro")
+		    p_val = -1;
+		  else
+		    error ("norm: unrecognized norm `%s'", p.c_str ());
+		}
+	      else
+		{
+		  p_val = p_arg.double_value ();
+
+		  if (error_state)
+		    error ("norm: unrecognized norm value");
+		}
+
+	      if (! error_state)
+		{
+		  if (x_arg.is_real_type ())
+		    {
+		      MArray<double> x (x_arg.array_value ());
+
+		      if (! error_state)
+			retval(0) = x.norm (p_val);
+		      else
+			error ("norm: expecting real vector");
+		    }
+		  else
+		    {
+		      MArray<Complex> x (x_arg.complex_array_value ());
+
+		      if (! error_state)
+			retval(0) = x.norm (p_val);
+		      else
+			error ("norm: expecting complex vector");
+		    }
+		}
+	    }
 	  else
-	    {
-	      error ("norm: unrecognized norm `%s'", p.c_str ());
-	      return retval;
-	    }
+	    retval = feval ("__norm__", args);
 	}
       else
-	{
-	  p_val = args(1).double_value ();
-
-	  if (error_state)
-	    {
-	      error ("norm: unrecognized norm value");
-	      return retval;
-	    }
-	}
-
-      octave_value x_arg = args(0);
-
-      if (x_arg.is_real_type ())
-	{
-	  ColumnVector x (x_arg.vector_value ());
-
-	  if (! error_state)
-	    retval = x.norm (p_val);
-	  else
-	    error ("norm: expecting real vector");
-	}
-      else
-	{
-	  ComplexColumnVector x (x_arg.complex_vector_value ());
-
-	  if (! error_state)
-	    retval = x.norm (p_val);
-	  else
-	    error ("norm: expecting complex vector");
-	}
+	error ("norm: only valid for 2-D objects");
     }
   else
     print_usage ();