changeset 12649:8579e7a6e6e0

Improve performance (2X) of svds by avoiding issymmetric calculation (bug #33073) * svds.m: Pass issym option to eigs() call. * eigs.cc: Avoid issymetric calculation if 'issym' option given.
author Rik <octave@nomad.inbox5.com>
date Thu, 05 May 2011 16:58:43 -0700
parents e205ebe2ba67
children b7f16997df4d
files scripts/sparse/svds.m src/DLD-FUNCTIONS/eigs.cc
diffstat 2 files changed, 21 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/sparse/svds.m
+++ b/scripts/sparse/svds.m
@@ -150,6 +150,8 @@
     ## Scale everything by the 1-norm to make things more stable.
     b = A / max_a;
     b_opts = opts;
+    ## Call to eigs is always a symmetric matrix by construction
+    b_opts.issym = true;
     b_opts.tol = opts.tol / max_a;
     b_sigma = sigma;
     if (!ischar (b_sigma))
--- a/src/DLD-FUNCTIONS/eigs.cc
+++ b/src/DLD-FUNCTIONS/eigs.cc
@@ -323,6 +323,7 @@
   bool a_is_complex = false;
   bool b_is_complex = false;
   bool symmetric = false;
+  bool sym_tested = false;
   bool cholB = false;
   bool a_is_sparse = false;
   ColumnVector permB;
@@ -399,7 +400,8 @@
           else
             acm = (args(0).complex_matrix_value());
           a_is_complex = true;
-          symmetric = false; // ARAPACK doesn't special case complex symmetric
+          symmetric = false; // ARPACK doesn't special case complex symmetric
+          sym_tested = true;
         }
       else
         {
@@ -407,19 +409,17 @@
             {
               asmm = (args(0).sparse_matrix_value());
               a_is_sparse = true;
-              symmetric = asmm.is_symmetric();
             }
           else
             {
               amm = (args(0).matrix_value());
-              symmetric = amm.is_symmetric();
             }
         }
 
     }
 
   // Note hold off reading B till later to avoid issues of double
-  // copies of the matrix if B is full/real while A is complex..
+  // copies of the matrix if B is full/real while A is complex.
   if (!error_state && nargin > 1 + arg_offset &&
       !(args(1 + arg_offset).is_real_scalar ()))
     {
@@ -481,10 +481,13 @@
             {
               octave_value tmp;
 
-              // issym is ignored if A is not a function
+              // issym is ignored for complex matrix inputs
               tmp = map.getfield ("issym");
-              if (tmp.is_defined () && have_a_fun)
-                symmetric = tmp.double_value () != 0.;
+              if (tmp.is_defined () && !sym_tested)
+                {
+                  symmetric = tmp.double_value () != 0.;
+                  sym_tested = true;
+                }
 
               // isreal is ignored if A is not a function
               tmp = map.getfield ("isreal");
@@ -543,6 +546,15 @@
       return retval;
     }
 
+  // Test undeclared (no issym) matrix inputs for symmetry
+  if (!sym_tested && !have_a_fun)
+    {
+      if (a_is_sparse)
+        symmetric = asmm.is_symmetric();
+      else
+        symmetric = amm.is_symmetric();
+    }
+
   if (have_b)
     {
       if (a_is_complex || b_is_complex)