changeset 20525:ff904ae0285b

eig: Return correct solution for a pair of hermitian matrices (bug #45511) * liboctave/numeric/EIG.cc (EIG::init): Use correct form of hermitian_init. * liboctave/numeric/fEIG.cc (FloatEIG::init): Likewise. * libinterp/corefcn/eig.cc: Add %!test cases. Thanks to Marco Caliari for identifying the fix.
author Mike Miller <mtmiller@octave.org>
date Tue, 15 Sep 2015 08:48:35 -0400
parents ba4088aee342
children 3f01c585f54e
files libinterp/corefcn/eig.cc liboctave/numeric/EIG.cc liboctave/numeric/fEIG.cc
diffstat 3 files changed, 14 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/eig.cc	Sun Sep 13 14:47:58 2015 -0700
+++ b/libinterp/corefcn/eig.cc	Tue Sep 15 08:48:35 2015 -0400
@@ -324,6 +324,18 @@
 %! assert (A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
 %! assert (A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
 
+%!test
+%! A = [1, 1+i; 1-i, 1];  B = [2, 0; 0, 2];
+%! [v, d] = eig (A, B);
+%! assert (A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps));
+%! assert (A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps));
+
+%!test
+%! A = single ([1, 1+i; 1-i, 1]);  B = single ([2, 0; 0, 2]);
+%! [v, d] = eig (A, B);
+%! assert (A * v(:, 1), d(1, 1) * B * v(:, 1), sqrt (eps ("single")));
+%! assert (A * v(:, 2), d(2, 2) * B * v(:, 2), sqrt (eps ("single")));
+
 %!error eig ()
 %!error eig ([1, 2; 3, 4], [4, 3; 2, 1], 1)
 %!error <EIG requires same size matrices> eig ([1, 2; 3, 4], 2)
--- a/liboctave/numeric/EIG.cc	Sun Sep 13 14:47:58 2015 -0700
+++ b/liboctave/numeric/EIG.cc	Tue Sep 15 08:48:35 2015 -0400
@@ -715,7 +715,7 @@
                              F77_CHAR_ARG_LEN (1)));
 
   if (a.is_hermitian () && b.is_hermitian () && info == 0)
-    return hermitian_init (a, calc_ev);
+    return hermitian_init (a, b, calc_ev);
 
   ComplexMatrix atmp = a;
   Complex *atmp_data = atmp.fortran_vec ();
--- a/liboctave/numeric/fEIG.cc	Sun Sep 13 14:47:58 2015 -0700
+++ b/liboctave/numeric/fEIG.cc	Tue Sep 15 08:48:35 2015 -0400
@@ -712,7 +712,7 @@
                              F77_CHAR_ARG_LEN (1)));
 
   if (a.is_hermitian () && b.is_hermitian () && info == 0)
-    return hermitian_init (a, calc_ev);
+    return hermitian_init (a, b, calc_ev);
 
   FloatComplexMatrix atmp = a;
   FloatComplex *atmp_data = atmp.fortran_vec ();