[PATCH] Use the inf-norm rather than 2-norm in issymmetric; add ishermitian.

Jason Riedy ejr at cs.berkeley.edu
Wed Dec 5 19:45:00 CST 2007


The current issymmetric uses the very expensive and densifying 2-norm,
plus it checks if the matrix is Hermitian rather than symmetric.  An
inf-norm tolerance probably is good enough.  A new routine handles
Hermitian cases.

Signed-off-by: Jason Riedy <ejr at cs.berkeley.edu>
---
  Tracking down that issymmetric was running me out of memory was
  no fun.  I'd be shocked if anyone relied on the 2-norm
  behavior, but symmetric v. Hermitian might run into problems.

  Also, Which test system is the right one?  I added routines to
  both.  If the DejaGnu one is unused, should it be deleted?

 scripts/ChangeLog                        |    9 +++++
 scripts/general/Makefile.in              |    8 ++--
 scripts/general/ishermitian.m            |   52 ++++++++++++++++++++++++++++++
 scripts/general/issymmetric.m            |   10 +++--
 test/ChangeLog                           |   12 +++++++
 test/octave.test/number/ishermitian-1.m  |    1 +
 test/octave.test/number/ishermitian-2.m  |    1 +
 test/octave.test/number/ishermitian-3.m  |    1 +
 test/octave.test/number/issymmetric-12.m |    1 +
 test/octave.test/number/number.exp       |   16 +++++++++
 test/test_number.m                       |   11 ++++++
 11 files changed, 114 insertions(+), 8 deletions(-)
 create mode 100644 scripts/general/ishermitian.m
 create mode 100644 test/octave.test/number/ishermitian-1.m
 create mode 100644 test/octave.test/number/ishermitian-2.m
 create mode 100644 test/octave.test/number/ishermitian-3.m
 create mode 100644 test/octave.test/number/issymmetric-12.m

diff --git a/scripts/ChangeLog b/scripts/ChangeLog
index a155160..a7418e8 100644
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,12 @@
+2007-12-05  Jason Riedy  <ejr at cs.berkeley.edu>
+
+	* general/issymmetric.m: To keep its argument sparse and the
+	function quick, use the infinity norm rather than the 2-norm.
+	Also measure the symmetric part rather than the Hermitian part.
+
+	* general/ishermitian.m: New file.  Measure the Hermitian part.
+	* general/Makefile.in: Add ishermitian.m to SOURCES.
+
 2007-12-04  John W. Eaton  <jwe at octave.org>
 
 	* plot/__go_draw_axes__.m: Omit "font \"NAME,SIZE\"" in gnuplot
diff --git a/scripts/general/Makefile.in b/scripts/general/Makefile.in
index c5256ea..4bb7230 100644
--- a/scripts/general/Makefile.in
+++ b/scripts/general/Makefile.in
@@ -38,10 +38,10 @@ SOURCES = __isequal__.m __splinen__.m accumarray.m arrayfun.m bicubic.m \
   celldisp.m circshift.m common_size.m cplxpair.m cumtrapz.m deal.m del2.m \
   diff.m flipdim.m fliplr.m flipud.m gradient.m ind2sub.m int2str.m interp1.m \
   interp2.m interp3.m interpn.m interpft.m is_duplicate_entry.m isa.m \
-  isdefinite.m isdir.m isequal.m isequalwithequalnans.m isscalar.m \
-  issquare.m issymmetric.m isvector.m logical.m logspace.m lookup.m mod.m \
-  nargchk.m nextpow2.m nthroot.m num2str.m perror.m pol2cart.m \
-  polyarea.m postpad.m prepad.m quadl.m randperm.m rat.m rem.m \
+  isdefinite.m isdir.m isequal.m isequalwithequalnans.m ishermitian.m \
+  isscalar.m issquare.m issymmetric.m isvector.m logical.m logspace.m \
+  lookup.m mod.m nargchk.m nextpow2.m nthroot.m num2str.m perror.m \
+  pol2cart.m polyarea.m postpad.m prepad.m quadl.m randperm.m rat.m rem.m \
   repmat.m rot90.m rotdim.m shift.m shiftdim.m sortrows.m \
   sph2cart.m strerror.m structfun.m sub2ind.m trapz.m tril.m triu.m
 
diff --git a/scripts/general/ishermitian.m b/scripts/general/ishermitian.m
new file mode 100644
index 0000000..5e176dd
--- /dev/null
+++ b/scripts/general/ishermitian.m
@@ -0,0 +1,52 @@
+## Copyright (C) 1996, 1997, 2002, 2003, 2004, 2005, 2006, 2007
+##               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 3 of the License, 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, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ishermitian (@var{x}, @var{tol})
+## If @var{x} is Hermitian within the tolerance specified by @var{tol},
+## then return the dimension of @var{x}.  Otherwise, return 0.  If
+## @var{tol} is omitted, use a tolerance equal to the machine precision.
+## Matrix @var{x} is considered symmetric if
+## @code{norm (@var{x} - @var{x}', inf) / norm (@var{x}, inf) < @var{tol}}.
+## @seealso{size, rows, columns, length, ismatrix, isscalar,
+## issquare, issymmetric, isvector}
+## @end deftypefn
+
+## Author: A. S. Hodel <scotte at eng.auburn.edu>
+## Created: August 1993
+## Adapted-By: jwe, Jason Riedy <ejr at cs.berkeley.edu>
+
+function retval = ishermitian (x,tol)
+
+  if (nargin == 1 || nargin == 2)
+    retval = issquare (x);
+    if (retval != 0)
+      if (nargin == 1)
+        tol = eps;
+      endif
+      norm_x = norm (x, inf);
+      if (norm_x != 0 && norm (x - x', inf) / norm_x > tol)
+        retval = 0;
+      endif
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
diff --git a/scripts/general/issymmetric.m b/scripts/general/issymmetric.m
index 75cea15..4367b94 100644
--- a/scripts/general/issymmetric.m
+++ b/scripts/general/issymmetric.m
@@ -22,13 +22,15 @@
 ## If @var{x} is symmetric within the tolerance specified by @var{tol},
 ## then return the dimension of @var{x}.  Otherwise, return 0.  If
 ## @var{tol} is omitted, use a tolerance equal to the machine precision.
-## @seealso{size, rows, columns, length, ismatrix, isscalar,
+## Matrix @var{x} is considered symmetric if
+## @code{norm (@var{x} - @var{x}.', inf) / norm (@var{x}, inf) < @var{tol}}.
+## @seealso{size, rows, columns, length, ishermitian, ismatrix, isscalar,
 ## issquare, isvector}
 ## @end deftypefn
 
 ## Author: A. S. Hodel <scotte at eng.auburn.edu>
 ## Created: August 1993
-## Adapted-By: jwe
+## Adapted-By: jwe, Jason Riedy <ejr at cs.berkeley.edu>
 
 function retval = issymmetric (x,tol)
 
@@ -38,8 +40,8 @@ function retval = issymmetric (x,tol)
       if (nargin == 1)
         tol = eps;
       endif
-      norm_x = norm (x);
-      if (norm_x != 0 && norm (x - x') / norm_x > tol)
+      norm_x = norm (x, inf);
+      if (norm_x != 0 && norm (x - x.', inf) / norm_x > tol)
         retval = 0;
       endif
     endif
diff --git a/test/ChangeLog b/test/ChangeLog
index de4fcbe..e9f0512 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,15 @@
+2007-12-05  Jason Riedy  <ejr at cs.berkeley.edu>
+
+	* test_number.m: Include the following tests by hand.
+	* octave.test/general/number.exp: Add tests.
+	* octave.test/general/issymmetric-12.m: New test.  Verify that the
+	routine tests for a symmetric matrix rather than a Hermitian one.
+	* octave.test/general/ishermitian-1.m: New test.
+	* octave.test/general/ishermitian-2.m: New test.  Verify that the
+	routine tests for a Hermitian matrix rather than a symmetric one.
+	* octave.test/general/ishermitian-3.m: New test.  Check TOL
+	parameter.
+
 2007-12-03  David Bateman  <dbateman at free.fr>
 
 	* fntests.m: Also count the skipped tests.
diff --git a/test/octave.test/number/ishermitian-1.m b/test/octave.test/number/ishermitian-1.m
new file mode 100644
index 0000000..8e10908
--- /dev/null
+++ b/test/octave.test/number/ishermitian-1.m
@@ -0,0 +1 @@
+ishermitian ([1, 2i; -2i, 1]) == 2
diff --git a/test/octave.test/number/ishermitian-2.m b/test/octave.test/number/ishermitian-2.m
new file mode 100644
index 0000000..995a42d
--- /dev/null
+++ b/test/octave.test/number/ishermitian-2.m
@@ -0,0 +1 @@
+ishermitian ([1, 2i; 2i, 1])
diff --git a/test/octave.test/number/ishermitian-3.m b/test/octave.test/number/ishermitian-3.m
new file mode 100644
index 0000000..633d30e
--- /dev/null
+++ b/test/octave.test/number/ishermitian-3.m
@@ -0,0 +1 @@
+ishermitian ([1, 2.1i; -2i, 1.1], 0.2) == 2
diff --git a/test/octave.test/number/issymmetric-12.m b/test/octave.test/number/issymmetric-12.m
new file mode 100644
index 0000000..68b50fa
--- /dev/null
+++ b/test/octave.test/number/issymmetric-12.m
@@ -0,0 +1 @@
+issymmetric ([1, 2i; -2i, 1])
diff --git a/test/octave.test/number/number.exp b/test/octave.test/number/number.exp
index 1d5eb5c..402fb88 100644
--- a/test/octave.test/number/number.exp
+++ b/test/octave.test/number/number.exp
@@ -205,3 +205,19 @@ do_test issymmetric-10.m
 set test issymmetric-11
 set prog_output "^usage:.*"
 do_test issymmetric-11.m
+
+set test issymmetric-12
+set prog_output "^ans = 0"
+do_test issymmetric-12.m
+
+set test ishermitian-1
+set prog_output "^ans = 1"
+do_test ishermitian-1.m
+
+set test ishermitian-2
+set prog_output "^ans = 0"
+do_test ishermitian-2.m
+
+set test ishermitian-3
+set prog_output "^ans = 1"
+do_test ishermitian-3.m
diff --git a/test/test_number.m b/test/test_number.m
index 93b4ff9..8998794 100644
--- a/test/test_number.m
+++ b/test/test_number.m
@@ -206,3 +206,14 @@
 %% test/octave.test/number/issymmetric-11.m
 %!error issymmetric ();
 
+%% test/octave.test/number/issymmetric-12.m
+%!assert(!issymmetric ([1, 2i; -2i, 1]));
+
+%% test/octave.test/number/ishermitian-1.m
+%!assert(ishermitian ([1, 2i; -2i, 1]) == 2);
+
+%% test/octave.test/number/ishermitian-2.m
+%!assert(!ishermitian ([1, 2i; 2i, 1]));
+
+%% test/octave.test/number/ishermitian-3.m
+%!assert(ishermitian ([1, 2.1i; -2i, 1.1], 0.2) == 2);
-- 
debian.1.5.3.7.1-dirty




More information about the Bug-octave mailing list