octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MacOSX: Octave.app 2.9.14


From: John W. Eaton
Subject: Re: MacOSX: Octave.app 2.9.14
Date: Wed, 03 Oct 2007 22:47:04 -0400

[I'm moving this from the help list, since we are way beyond help
now.  --jwe]

On  3-Oct-2007, Dmitri A. Sergatskov wrote:

| On 10/3/07, John W. Eaton <address@hidden> wrote:
| 
| > Is
| >
| >   sum (x .* x)
| >
| > really faster here than
| >
| >   sumsq (x)
| >
| > ?
| 
| No. sumsq is faster (at least on my machine).
| But I am confused, isn't call to __vnorm__
| better yet?

D'oh.  There is already a call to __vnorm__ in the current norm.m.
The code we've been modifying only applies in the case of integer or
sparse vectors.

Anyway, what about the following patch?  It makes norm a built-in
function but calls an external __norm__.m function for cases it can't
handle.  Currently the C++ code only handles what __vnorm__ did
before.  But this removes the overhead of a .m file function for the
cases handled by __vnorm__.

David, does this look OK to you?  With the patch, I see (for example):

  octave:32> x = rand (100000000, 1);
  octave:33> t = cputime; sqrt (sumsq (x)); cputime-t
  ans =  7.9325
  octave:34> t = cputime; norm (x); cputime-t
  ans =  0.29202
  octave:38> sqrt (sumsq (x))
  ans =  5773.5
  octave:39> norm (x)
  ans =  5773.5

but this is an extreme case.  But the old norm function was actually
faster for me on this than the "sqrt (sumsq (x))", but I think much
worse on memory usage becuase of the stupid way that the
octave_value::vector_value function used by __vnorm__ is implemented.
It looks to me like all of the following functions in the octave_value
class need some serious re-thinking, but I think that can wait until
after 3.0.

  column_vector_value
  complex_column_vector_value
  row_vector_value
  complex_row_vector_value
  vector_value
  int_vector_value
  complex_vector_value


jwe

scripts/ChangeLog:

2007-10-03  John W. Eaton  <address@hidden>

        * linear-algebra/Makefile.in (SOURCES): Rename norm.m to __norm__.m.
        * linear-algebra/__norm__.m: Rename from norm.m.  Eliminate
        special for __vnorm__.

src/ChangeLog:

2007-10-03  John W. Eaton  <address@hidden>

        * data.cc (Fnorm): New function.
        (F__vnorm__): Delete.


Index: scripts/linear-algebra/Makefile.in
===================================================================
RCS file: /cvs/octave/scripts/linear-algebra/Makefile.in,v
retrieving revision 1.22
diff -u -u -r1.22 Makefile.in
--- scripts/linear-algebra/Makefile.in  25 Jul 2007 15:49:17 -0000      1.22
+++ scripts/linear-algebra/Makefile.in  4 Oct 2007 02:31:54 -0000
@@ -20,8 +20,8 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 
-SOURCES = commutation_matrix.m cond.m cross.m dmult.m dot.m \
-  duplication_matrix.m housh.m krylov.m krylovb.m logm.m norm.m \
+SOURCES = __norm__.m commutation_matrix.m cond.m cross.m dmult.m \
+  dot.m duplication_matrix.m housh.m krylov.m krylovb.m logm.m \
   null.m orth.m qzhess.m rank.m rref.m trace.m vec.m vech.m
 
 DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
Index: scripts/linear-algebra/__norm__.m
===================================================================
RCS file: scripts/linear-algebra/__norm__.m
diff -N scripts/linear-algebra/__norm__.m
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ scripts/linear-algebra/__norm__.m   4 Oct 2007 02:31:54 -0000
@@ -0,0 +1,93 @@
+## Copyright (C) 1996, 1997 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## Undocumented internal function.
+
+## Author: jwe
+
+function retval = __norm__ (x, p)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (isempty (x))
+    retval = [];
+    return;
+  endif
+
+  if (ndims (x) > 2)
+    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 (ndims(x) == 2 && (rows (x) == 1 || columns (x) == 1))
+    if (ischar (p))
+      if (strcmp (p, "fro"))
+       retval = sqrt (sum (abs (x) .^ 2));
+      elseif (strcmp (p, "inf"))
+        retval = max (abs (x));
+      else
+        error ("norm: unrecognized norm");
+      endif
+    else
+      if (p == Inf)
+        retval = max (abs (x));
+      elseif (p == -Inf)
+        retval = min (abs (x));
+      elseif (p == 1)
+       retval = sum (abs (x));
+      elseif (p == 2)
+        if (iscomplex (x))
+          x = abs (x);
+        endif
+        retval = sqrt (sumsq (x));
+      else
+        retval = sum (abs (x) .^ p) ^ (1/p);
+      endif
+    endif
+  else
+    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 vector norm");
+      endif
+    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
Index: scripts/linear-algebra/norm.m
===================================================================
RCS file: scripts/linear-algebra/norm.m
diff -N scripts/linear-algebra/norm.m
--- scripts/linear-algebra/norm.m       3 Oct 2007 21:36:42 -0000       1.33
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,152 +0,0 @@
-## Copyright (C) 1996, 1997 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, write to the Free
-## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-## 02110-1301, USA.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} norm (@var{a}, @var{p})
-## Compute the p-norm of the matrix @var{a}.  If the second argument is
-## missing, @code{p = 2} is assumed.
-##
-## If @var{a} is a matrix:
-##
-## @table @asis
-## @item @var{p} = @code{1}
-## 1-norm, the largest column sum of the absolute values of @var{a}.
-##
-## @item @var{p} = @code{2}
-## Largest singular value of @var{a}.
-##
-## @item @var{p} = @code{Inf}
-## @cindex infinity norm
-## Infinity norm, the largest row sum of the absolute values of @var{a}.
-##
-## @item @var{p} = @code{"fro"}
-## @cindex Frobenius norm
-## Frobenius norm of @var{a}, @code{sqrt (sum (diag (@var{a}' * @var{a})))}.
-## @end table
-##
-## If @var{a} is a vector or a scalar:
-##
-## @table @asis
-## @item @var{p} = @code{Inf}
-## @code{max (abs (@var{a}))}.
-##
-## @item @var{p} = @code{-Inf}
-## @code{min (abs (@var{a}))}.
-##
-## @item other
-## p-norm of @var{a}, @code{(sum (abs (@var{a}) .^ @var{p})) ^ (1/@var{p})}.
-## @end table
-## @seealso{cond, svd}
-## @end deftypefn
-
-## Author: jwe
-
-function retval = norm (x, p)
-
-  if (nargin < 1 || nargin > 2)
-    print_usage ();
-  endif
-
-  if (isempty (x))
-    retval = [];
-    return;
-  endif
-
-  if (ndims (x) > 2)
-    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 (ndims(x) == 2 && (rows (x) == 1 || columns (x) == 1))
-    if (isinteger (x) || issparse (x))
-      if (ischar (p))
-        if (strcmp (p, "fro"))
-         retval = sqrt (sum (abs (x) .^ 2));
-        elseif (strcmp (p, "inf"))
-          retval = max (abs (x));
-        else
-          error ("norm: unrecognized norm");
-        endif
-      else
-        if (p == Inf)
-          retval = max (abs (x));
-        elseif (p == -Inf)
-          retval = min (abs (x));
-       elseif (p == 1)
-         retval = sum (abs (x));
-       elseif (p == 2)
-          if (iscomplex (x))
-            x = abs (x);
-          endif
-          retval = sqrt (sum (x .* x));
-        else
-          retval = sum (abs (x) .^ p) ^ (1/p);
-        endif
-      endif
-    else
-      retval = __vnorm__ (x, p);
-    endif
-  else
-    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 vector norm");
-      endif
-    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);
-%!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);
Index: src/data.cc
===================================================================
RCS file: /cvs/octave/src/data.cc,v
retrieving revision 1.182
diff -u -u -r1.182 data.cc
--- src/data.cc 2 Oct 2007 20:47:22 -0000       1.182
+++ src/data.cc 4 Oct 2007 02:31:58 -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 "utils.h"
-#include "Cell.h"
-#include "oct-map.h"
+#include "parse.h"
 #include "pt-mat.h"
+#include "utils.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\
address@hidden {Built-in Function} {} __vnorm__ (@var{x}, @var{p})\n\
-Undocumented internal function.\n\
address@hidden {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\
address@hidden @asis\n\
address@hidden @var{p} = @code{1}\n\
+1-norm, the largest column sum of the absolute values of @var{a}.\n\
+\n\
address@hidden @var{p} = @code{2}\n\
+Largest singular value of @var{a}.\n\
+\n\
address@hidden @var{p} = @code{Inf}\n\
address@hidden infinity norm\n\
+Infinity norm, the largest row sum of the absolute values of @var{a}.\n\
+\n\
address@hidden @var{p} = @code{\"fro\"}\n\
address@hidden Frobenius norm\n\
+Frobenius norm of @var{a}, @code{sqrt (sum (diag (@var{a}' * @var{a})))}.\n\
address@hidden table\n\
+\n\
+If @var{a} is a vector or a scalar:\n\
+\n\
address@hidden @asis\n\
address@hidden @var{p} = @code{Inf}\n\
address@hidden (abs (@var{a}))}.\n\
+\n\
address@hidden @var{p} = @code{-Inf}\n\
address@hidden (abs (@var{a}))}.\n\
+\n\
address@hidden other\n\
+p-norm of @var{a}, @code{(sum (abs (@var{a}) .^ @var{p})) ^ (1/@var{p})}.\n\
address@hidden table\n\
address@hidden, 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 x_arg = args(0);
 
-      octave_value p_arg;
+      if (x_arg.is_empty ())
+       retval(0) = 0.0;
+      else if (x_arg.ndims () == 2)
+       {
+         if ((x_arg.rows () == 1 || x_arg.columns () == 1)
+             && ! (x_arg.is_sparse_type () || x_arg.is_integer_type ()))
+           {
+             double p_val;
 
-      if (nargin == 1)
-       p_arg = 2;
-      else
-       p_arg = args(1);
+             octave_value p_arg;
 
-      if (p_arg.is_string ())
-       {
-         std::string p = args(1).string_value ();
+             if (nargin == 1)
+               p_arg = 2;
+             else
+               p_arg = args(1);
 
-         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 (p_arg.is_string ())
+               {
+                 std::string p = args(1).string_value ();
 
-         if (error_state)
-           {
-             error ("norm: unrecognized norm value");
-             return retval;
-           }
-       }
+                 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 ();
 
-      octave_value x_arg = args(0);
+                 if (error_state)
+                   error ("norm: unrecognized norm value");
+               }
 
-      if (x_arg.is_real_type ())
-       {
-         ColumnVector x (x_arg.vector_value ());
+             if (! error_state)
+               {
+                 if (x_arg.is_real_type ())
+                   {
+                     MArray<double> x (x_arg.array_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(0) = x.norm (p_val);
+                     else
+                       error ("norm: expecting real vector");
+                   }
+                 else
+                   {
+                     MArray<Complex> x (x_arg.complex_array_value ());
 
-         if (! error_state)
-           retval = x.norm (p_val);
+                     if (! error_state)
+                       retval(0) = x.norm (p_val);
+                     else
+                       error ("norm: expecting complex vector");
+                   }
+               }
+           }
          else
-           error ("norm: expecting complex vector");
+           retval = feval ("__norm__", args);
        }
+      else
+       error ("norm: only valid for 2-D objects");
     }
   else
     print_usage ();

reply via email to

[Prev in Thread] Current Thread [Next in Thread]