diff libinterp/dldfcn/__eigs__.cc @ 27683:6604b41ca63f

Return only real eigenvalues from eigs() for symmetric matrices (bug #57196). * __eigs__.cc (F__eigs__): Test complex matrices for symmettry (Hermitian). If found, take the real() part of the result from ARPACK before returning the values.
author Rik <rik@octave.org>
date Wed, 13 Nov 2019 09:37:26 -0800
parents 041caa61ed34
children e557774a2604
line wrap: on
line diff
--- a/libinterp/dldfcn/__eigs__.cc	Tue Nov 12 15:39:05 2019 +0100
+++ b/libinterp/dldfcn/__eigs__.cc	Wed Nov 13 09:37:26 2019 -0800
@@ -231,8 +231,6 @@
           else
             acm = (args(0).complex_matrix_value ());
           a_is_complex = true;
-          symmetric = false;  // ARPACK doesn't special case complex symmetric
-          sym_tested = true;
         }
       else
         {
@@ -464,9 +462,19 @@
         }
 
       if (nargout < 2)
-        retval(0) = eig_val;
+        {
+          if (symmetric)
+            retval(0) = real (eig_val);
+          else
+            retval(0) = eig_val;
+        }
       else
-        retval = ovl (eig_vec, ComplexDiagMatrix (eig_val), double (info));
+        {
+          if (symmetric)
+            retval = ovl (eig_vec, DiagMatrix (real (eig_val)), double (info));
+          else
+            retval = ovl (eig_vec, ComplexDiagMatrix (eig_val), double (info));
+        }
     }
   else if (sigmai != 0.0)
     {
@@ -502,9 +510,19 @@
         }
 
       if (nargout < 2)
-        retval(0) = eig_val;
+        {
+          if (symmetric)
+            retval(0) = real (eig_val);
+          else
+            retval(0) = eig_val;
+        }
       else
-        retval = ovl (eig_vec, ComplexDiagMatrix (eig_val), double (info));
+        {
+          if (symmetric)
+            retval = ovl (eig_vec, DiagMatrix (real (eig_val)), double (info));
+          else
+            retval = ovl (eig_vec, ComplexDiagMatrix (eig_val), double (info));
+        }
     }
   else
     {