changeset 6508:184ab67c3bc1

[project @ 2007-04-07 00:43:09 by jwe]
author jwe
date Sat, 07 Apr 2007 00:43:10 +0000
parents 679c2f987943
children 84f2d0253aea
files libcruft/ChangeLog libcruft/blas-xtra/Makefile.in libcruft/blas-xtra/xdnrm2.f libcruft/blas-xtra/xdznrm2.f liboctave/ChangeLog liboctave/MArray-C.cc liboctave/MArray-d.cc liboctave/MArray-defs.h liboctave/MArray.cc liboctave/MArray.h scripts/ChangeLog scripts/linear-algebra/norm.m src/ChangeLog src/data.cc
diffstat 14 files changed, 266 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/libcruft/ChangeLog	Fri Apr 06 20:00:38 2007 +0000
+++ b/libcruft/ChangeLog	Sat Apr 07 00:43:10 2007 +0000
@@ -1,5 +1,8 @@
 2007-04-06  John W. Eaton  <jwe@octave.org>
 
+	* blas-xtra/xdnrm2.f, blas-xtra/xdznrm2.f: New functions.
+	* blas-xtra/Makefile.in (FSRC): Add them to the list.
+
 	* ranlib/phrtsd.f (phrtsd): Ensure that the types of the arguments
 	passed to mod are the same even on 64-bit systems.
 
--- a/libcruft/blas-xtra/Makefile.in	Fri Apr 06 20:00:38 2007 +0000
+++ b/libcruft/blas-xtra/Makefile.in	Sat Apr 07 00:43:10 2007 +0000
@@ -14,7 +14,7 @@
 
 EXTERNAL_DISTFILES = $(DISTFILES)
 
-FSRC = xddot.f xerbla.f xzdotu.f
+FSRC = xddot.f xdnrm2.f xdznrm2.f xerbla.f xzdotu.f
 
 include $(TOPDIR)/Makeconf
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcruft/blas-xtra/xdnrm2.f	Sat Apr 07 00:43:10 2007 +0000
@@ -0,0 +1,6 @@
+      subroutine xdnrm2 (n, x, incx, retval)
+      double precision dnrm2, x(*), retval
+      integer n, incx
+      retval = dnrm2 (n, x, incx);
+      return
+      end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcruft/blas-xtra/xdznrm2.f	Sat Apr 07 00:43:10 2007 +0000
@@ -0,0 +1,7 @@
+      subroutine xdznrm2 (n, x, incx, retval)
+      double precision dznrm2, retval
+      double complex x(*)
+      integer n, incx
+      retval = dznrm2 (n, x, incx);
+      return
+      end
--- a/liboctave/ChangeLog	Fri Apr 06 20:00:38 2007 +0000
+++ b/liboctave/ChangeLog	Sat Apr 07 00:43:10 2007 +0000
@@ -1,3 +1,11 @@
+2007-04-06  John W. Eaton  <jwe@octave.org>
+
+	* MArray-defs.h (MARRAY_NORM_BODY): New macro.
+	* MArray.h (MArray<T>::norm): New function.
+	* MArray.cc: Provide decl.
+	* MArray-d.cc (MArray<double>::norm): Define double specialization.
+	* MArray-C.cc (MArray<Complex>::norm): Define Complex specialization.
+
 2007-04-04  John W. Eaton  <jwe@octave.org>
 
 	* Range.cc (Range::nelem_internal): Likewise.
--- a/liboctave/MArray-C.cc	Fri Apr 06 20:00:38 2007 +0000
+++ b/liboctave/MArray-C.cc	Sat Apr 07 00:43:10 2007 +0000
@@ -28,10 +28,25 @@
 // Instantiate MArrays of Complex values.
 
 #include "oct-cmplx.h"
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (xdznrm2, XDZNRM2) (const octave_idx_type&, const Complex*,
+			       const octave_idx_type&, double&);
+}
 
 #include "MArray.h"
 #include "MArray.cc"
 
+template <>
+double
+MArray<Complex>::norm (double p) const
+{
+  MARRAY_NORM_BODY (Complex, xdznrm2, XDZNRM2);
+}
+
 template class OCTAVE_API MArray<Complex>;
 
 INSTANTIATE_MARRAY_FRIENDS (Complex)
--- a/liboctave/MArray-d.cc	Fri Apr 06 20:00:38 2007 +0000
+++ b/liboctave/MArray-d.cc	Sat Apr 07 00:43:10 2007 +0000
@@ -27,9 +27,25 @@
 
 // Instantiate MArrays of double values.
 
+#include "f77-fcn.h"
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (xdnrm2, XDNRM2) (const octave_idx_type&, const double*,
+			     const octave_idx_type&, double&);
+}
+
 #include "MArray.h"
 #include "MArray.cc"
 
+template <>
+double
+MArray<double>::norm (double p) const
+{
+  MARRAY_NORM_BODY (double, xdnrm2, XDNRM2);
+}
+
 template class MArray<double>;
 
 INSTANTIATE_MARRAY_FRIENDS (double)
--- a/liboctave/MArray-defs.h	Fri Apr 06 20:00:38 2007 +0000
+++ b/liboctave/MArray-defs.h	Sat Apr 07 00:43:10 2007 +0000
@@ -321,6 +321,78 @@
   MDIAGARRAY2_DADA_BINOP_FWD_DEFS \
     (R, T, dynamic_cast<const B<T>&>, R, dynamic_cast<const B<T>&>, R)
 
+#define MARRAY_NORM_BODY(TYPE, blas_norm, BLAS_NORM)	\
+ \
+  double retval = octave_NaN; \
+ \
+  octave_idx_type len = length (); \
+ \
+  if (len > 0) \
+    { \
+      const TYPE *d = data (); \
+ \
+      if (p == -1) \
+	{ \
+	  /* Frobenius norm.  */ \
+	  retval = 0; \
+ \
+	  for (octave_idx_type i = 0; i < len; i++) \
+	    { \
+	      double d_abs = std::abs (d[i]); \
+	      retval += d_abs * d_abs; \
+	    } \
+ \
+	  retval = ::sqrt (retval); \
+	} \
+      else if (p == 2) \
+	F77_FCN (blas_norm, BLAS_NORM) (len, d, 1, retval); \
+      else if (xisinf (p)) \
+	{ \
+	  octave_idx_type i = 0; \
+ \
+	  while (i < len && xisnan (d[i])) \
+	    i++; \
+ \
+	  if (i < len) \
+	    retval = std::abs (d[i]); \
+ \
+	  if (p > 0) \
+	    { \
+	      while (i < len) \
+		{ \
+		  double d_abs = std::abs (d[i++]); \
+ \
+		  if (d_abs > retval) \
+		    retval = d_abs; \
+		} \
+	    } \
+	  else \
+	    { \
+	      while (i < len) \
+		{ \
+		  double d_abs = std::abs (d[i++]); \
+ \
+		  if (d_abs < retval) \
+		    retval = d_abs; \
+		} \
+	    } \
+	} \
+      else \
+	{ \
+	  retval = 0; \
+ \
+	  for (octave_idx_type i = 0; i < len; i++) \
+	    { \
+	      double d_abs = std::abs (d[i]); \
+	      retval += pow (d_abs, p); \
+	    } \
+ \
+	  retval = pow (retval, 1/p); \
+	} \
+    } \
+ \
+  return retval
+
 // Now we have all the definitions we need.
 
 #endif
--- a/liboctave/MArray.cc	Fri Apr 06 20:00:38 2007 +0000
+++ b/liboctave/MArray.cc	Sat Apr 07 00:43:10 2007 +0000
@@ -33,6 +33,16 @@
 
 // One dimensional array with math ops.
 
+template <class T>
+double
+MArray<T>::norm (double) const
+{
+  (*current_liboctave_error_handler)
+    ("norm: only implemented for double and complex values");
+
+  return 0;
+}
+
 // Element by element MArray by scalar ops.
 
 template <class T>
--- a/liboctave/MArray.h	Fri Apr 06 20:00:38 2007 +0000
+++ b/liboctave/MArray.h	Sat Apr 07 00:43:10 2007 +0000
@@ -80,6 +80,7 @@
       return retval;
     }
 
+  double norm (double p) const;
 
   // Currently, the OPS functions don't need to be friends, but that
   // may change.
--- a/scripts/ChangeLog	Fri Apr 06 20:00:38 2007 +0000
+++ b/scripts/ChangeLog	Sat Apr 07 00:43:10 2007 +0000
@@ -1,3 +1,11 @@
+2007-04-06  John W. Eaton  <jwe@octave.org>
+
+	* linear-algebra/norm.m: Use new __vnorm__ function for vector args.
+
+2007-04-06  Daniel J Sebald  <daniel.sebald@ieee.org>
+
+	* plot/stem.m: Use plot instead of a series of calls to line.
+
 2007-04-05  John W. Eaton  <jwe@octave.org>
 
 	* sparse/nonzeros.m, sparse/normest.m, sparse/spconvert.m,
--- a/scripts/linear-algebra/norm.m	Fri Apr 06 20:00:38 2007 +0000
+++ b/scripts/linear-algebra/norm.m	Sat Apr 07 00:43:10 2007 +0000
@@ -69,14 +69,17 @@
   endif
 
   if (ndims (x) > 2)
-    error ("norm: Only valid on 2-D objects")
+    error ("norm: only valid on 2-D objects")
+  endif
+
+  if (nargin == 1)
+    p = 2;
   endif
 
   ## Do we have a vector or matrix as the first argument?
 
-  if (rows (x) == 1 || columns (x) == 1)
-
-    if (nargin == 2)
+  if (is_vector (x))
+    if (isinteger (x) || issparse (x))
       if (ischar (p))
         if (strcmp (p, "fro"))
 	  retval = sqrt (sum (abs (x) .^ 2));
@@ -94,36 +97,48 @@
           retval = sum (abs (x) .^ p) ^ (1/p);
         endif
       endif
-    elseif (nargin == 1)
-      retval = sqrt (sum (abs (x) .^ 2));
+    else
+      retval = __vnorm__ (x, p);
     endif
-
   else
-
-    if (nargin == 2)
-      if (ischar (p))
-        if (strcmp (p, "fro"))
-	  retval = sqrt (sum (sum (abs (x) .^ 2)));
-        elseif (strcmp (p, "inf"))
-          retval = max (sum (abs (x')));
-        else
-          error ("norm: unrecognized norm");
-        endif
+    if (ischar (p))
+      if (strcmp (p, "fro"))
+	retval = sqrt (sum (sum (abs (x) .^ 2)));
+      elseif (strcmp (p, "inf"))
+        retval = max (sum (abs (x')));
       else
-        if (p == 1)
-          retval = max (sum (abs (x)));
-        elseif (p == 2)
-          s = svd (x);
-          retval = s (1);
-        elseif (p == Inf)
-          retval = max (sum (abs (x')));
-        endif
+        error ("norm: unrecognized vector norm");
       endif
-    elseif (nargin == 1)
-      s = svd (x);
-      retval = s (1);
+    else
+      if (p == 1)
+        retval = max (sum (abs (x)));
+      elseif (p == 2)
+        s = svd (x);
+        retval = s (1);
+      elseif (p == Inf)
+        retval = max (sum (abs (x')));
+      else
+	error ("norm: unrecognized matrix norm");
+      endif
     endif
-
   endif
 
 endfunction
+
+%!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);
+%!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);
--- a/src/ChangeLog	Fri Apr 06 20:00:38 2007 +0000
+++ b/src/ChangeLog	Sat Apr 07 00:43:10 2007 +0000
@@ -1,5 +1,7 @@
 2007-04-06  John W. Eaton  <jwe@octave.org>
 
+	* data.cc (F__vnorm__): New function.
+
 	* pt-fcn-handle.cc (tree_anon_fcn_handle::param_list, 
 	tree_anon_fcn_handle::cmd_list,	tree_anon_fcn_handle::ret_list,
 	tree_anon_fcn_handle::sym_tab): Delete.  Remove all uses.
--- a/src/data.cc	Fri Apr 06 20:00:38 2007 +0000
+++ b/src/data.cc	Sat Apr 07 00:43:10 2007 +0000
@@ -2583,6 +2583,79 @@
   return retval;
 }
 
+DEFUN (__vnorm__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __vnorm__ (@var{x}, @var{p})\n\
+Compute various norms of the vector @var{x}.\n\
+@end deftypefn")
+{
+  octave_value 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 ())
+	{
+	  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 ());
+	      return retval;
+	    }
+	}
+      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");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***