summaryrefslogtreecommitdiff
path: root/packages/base/src/Internal
diff options
context:
space:
mode:
authorMaxim Koltsov <kolmax94@gmail.com>2018-11-13 15:39:55 +0300
committerMaxim Koltsov <kolmax94@gmail.com>2018-11-13 15:39:55 +0300
commitcc737710b4878a387ea8090f9c2330b1e8d73f38 (patch)
tree02fc9ff241d06ac168e6a6cc19ecfd8e6ce8f812 /packages/base/src/Internal
parentacb57ec8dd3011534813bdbee84563f1a830f499 (diff)
Fix geig for complex eigenvalues, add tests
eigG was incorrectly returning eigenvectors corresponding to complex eigenvalues. This was discovered with tests for geig, which are also added to the repo.
Diffstat (limited to 'packages/base/src/Internal')
-rw-r--r--packages/base/src/Internal/LAPACK.hs10
1 files changed, 9 insertions, 1 deletions
diff --git a/packages/base/src/Internal/LAPACK.hs b/packages/base/src/Internal/LAPACK.hs
index b834b20..c9f5d0f 100644
--- a/packages/base/src/Internal/LAPACK.hs
+++ b/packages/base/src/Internal/LAPACK.hs
@@ -302,6 +302,14 @@ fixeig ((r1:+i1):(r2:+i2):r) (v1:v2:vs)
302 | otherwise = comp' v1 : fixeig ((r2:+i2):r) (v2:vs) 302 | otherwise = comp' v1 : fixeig ((r2:+i2):r) (v2:vs)
303fixeig _ _ = error "fixeig with impossible inputs" 303fixeig _ _ = error "fixeig with impossible inputs"
304 304
305-- For dggev alpha(i) / beta(i), alpha(i+1) / beta(i+1) form a complex conjugate pair when Im alpha(i) != 0.
306-- However, this does not lead to Re alpha(i) == Re alpha(i+1), since beta(i) and beta(i+1)
307-- can be different. Therefore old 'fixeig' would fail for 'eigG'.
308fixeigG [] _ = []
309fixeigG [_] [v] = [comp' v]
310fixeigG ((ar1:+ai1) : an : as) (v1:v2:vs)
311 | abs ai1 > 1e-13 = toComplex' (v1, v2) : toComplex' (v1, mapVector negate v2) : fixeigG as vs
312 | otherwise = comp' v1 : fixeigG (an:as) (v2:vs)
305 313
306-- | Eigenvalues of a general real matrix, using LAPACK's /dgeev/ with jobz == \'N\'. 314-- | Eigenvalues of a general real matrix, using LAPACK's /dgeev/ with jobz == \'N\'.
307-- The eigenvalues are not sorted. 315-- The eigenvalues are not sorted.
@@ -316,7 +324,7 @@ eigG a b = (alpha', beta, v'')
316 (alpha, beta, v) = eigGaux dggev a b "eigG" 324 (alpha, beta, v) = eigGaux dggev a b "eigG"
317 alpha' = fixeig1 alpha 325 alpha' = fixeig1 alpha
318 v' = toRows $ trans v 326 v' = toRows $ trans v
319 v'' = fromColumns $ fixeig (toList alpha') v' 327 v'' = fromColumns $ fixeigG (toList alpha') v'
320 328
321eigGaux f ma mb st = unsafePerformIO $ do 329eigGaux f ma mb st = unsafePerformIO $ do
322 a <- copy ColumnMajor ma 330 a <- copy ColumnMajor ma