changeset 23141:bfa4ad642fa0

Disallow p-norm of -Inf for matrices (bug #50194). * data.cc: Add BIST tests for matrices with p==3, Hamming norm of a vector, and error case of p==-Inf for matrix. * oct-norm.cc (p_less1_gripe): Change error message to "p must be >= 1" for clarity. * oct-norm.cc (svd_matrix_norm, matrix_norm): Only proceed to calculate matrix Inf norm if p is infinite and p > 1, i.e., positive Inf.
author Rik <rik@octave.org>
date Thu, 02 Feb 2017 20:47:09 -0800
parents e66b3bfea380
children 36983345732b
files libinterp/corefcn/data.cc liboctave/numeric/oct-norm.cc
diffstat 2 files changed, 11 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/data.cc	Thu Feb 02 17:25:59 2017 -0500
+++ b/libinterp/corefcn/data.cc	Thu Feb 02 20:47:09 2017 -0800
@@ -5660,6 +5660,7 @@
 /*
 %!shared x
 %! x = [1, -3, 4, 5, -7];
+%!assert (norm (x,0), 5)
 %!assert (norm (x,1), 20)
 %!assert (norm (x,2), 10)
 %!assert (norm (x,3), 8.24257059961711, -4*eps)
@@ -5674,6 +5675,7 @@
 %! m = magic (4);
 %!assert (norm (m,1), 34)
 %!assert (norm (m,2), 34, -eps)
+%!assert (norm (m,3), 34, -sqrt (eps))
 %!assert (norm (m,Inf), 34)
 %!assert (norm (m,"inf"), 34)
 %!shared m2, flo, fhi
@@ -5685,6 +5687,7 @@
 
 %!shared x
 %! x = single ([1, -3, 4, 5, -7]);
+%!assert (norm (x,0), single (5))
 %!assert (norm (x,1), single (20))
 %!assert (norm (x,2), single (10))
 %!assert (norm (x,3), single (8.24257059961711), -4*eps ("single"))
@@ -5699,6 +5702,7 @@
 %! m = single (magic (4));
 %!assert (norm (m,1), single (34))
 %!assert (norm (m,2), single (34), -eps ("single"))
+%!assert (norm (m,3), single (34), -sqrt (eps ("single")))
 %!assert (norm (m,Inf), single (34))
 %!assert (norm (m,"inf"), single (34))
 %!shared m2, flo, fhi
@@ -5708,6 +5712,9 @@
 %!assert (norm (flo*m2,"fro"), single (sqrt (30)*flo), -eps ("single"))
 %!assert (norm (fhi*m2,"fro"), single (sqrt (30)*fhi), -eps ("single"))
 
+## Hamming norm (p == 0)
+%!assert (norm ([1, 0, 0, 0, 1], 0), 2)
+
 %!shared q
 %! q = rand (1e3, 3);
 %!assert (norm (q, 3, "rows"), sum (q.^3, 2).^(1/3), sqrt (eps))
@@ -5734,6 +5741,7 @@
 %!error <unrecognized option> norm (1, "invalid", "rows")
 %!error <invalid combination of options> norm (1, "cols", "rows")
 %!error <invalid combination of options> norm (1, "rows", "rows")
+%!error <p must be .= 1> norm (ones (2,2), -Inf)
 */
 
 static octave_value
--- a/liboctave/numeric/oct-norm.cc	Thu Feb 02 17:25:59 2017 -0500
+++ b/liboctave/numeric/oct-norm.cc	Thu Feb 02 20:47:09 2017 -0800
@@ -471,7 +471,7 @@
 
 // derive column vector and SVD types
 
-static const char *p_less1_gripe = "xnorm: p must be at least 1";
+static const char *p_less1_gripe = "xnorm: p must be >= 1";
 
 // Static constant to control the maximum number of iterations.  100 seems to
 // be a good value.  Eventually, we can provide a means to change this
@@ -491,7 +491,7 @@
     }
   else if (p == 1)
     res = xcolnorms (m, 1).max ();
-  else if (lo_ieee_isinf (p))
+  else if (lo_ieee_isinf (p) && p > 1)
     res = xrownorms (m, 1).max ();
   else if (p > 1)
     {
@@ -512,7 +512,7 @@
   R res = 0;
   if (p == 1)
     res = xcolnorms (m, 1).max ();
-  else if (lo_ieee_isinf (p))
+  else if (lo_ieee_isinf (p) && p > 1)
     res = xrownorms (m, 1).max ();
   else if (p > 1)
     {