diff options
author | Dominic Steinitz <dominic@steinitz.org> | 2017-03-21 17:35:43 +0000 |
---|---|---|
committer | Dominic Steinitz <dominic@steinitz.org> | 2017-03-21 17:35:43 +0000 |
commit | 49d718705d205d62aea2762445f95735a671f305 (patch) | |
tree | 589b5c4396647f48b941d313432647ecb53ef606 /packages/base/src/Internal/Algorithms.hs | |
parent | fa1642dcf26f1da0a6f4c1324bcd1e8baf9fd478 (diff) |
Add tridiagonal solver and tests for it and triagonal solver.
Diffstat (limited to 'packages/base/src/Internal/Algorithms.hs')
-rw-r--r-- | packages/base/src/Internal/Algorithms.hs | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/packages/base/src/Internal/Algorithms.hs b/packages/base/src/Internal/Algorithms.hs index 23a5e13..99c9e34 100644 --- a/packages/base/src/Internal/Algorithms.hs +++ b/packages/base/src/Internal/Algorithms.hs | |||
@@ -62,6 +62,7 @@ class (Numeric t, | |||
62 | linearSolve' :: Matrix t -> Matrix t -> Matrix t | 62 | linearSolve' :: Matrix t -> Matrix t -> Matrix t |
63 | cholSolve' :: Matrix t -> Matrix t -> Matrix t | 63 | cholSolve' :: Matrix t -> Matrix t -> Matrix t |
64 | triSolve' :: UpLo -> Matrix t -> Matrix t -> Matrix t | 64 | triSolve' :: UpLo -> Matrix t -> Matrix t -> Matrix t |
65 | triDiagSolve' :: Vector t -> Vector t -> Vector t -> Matrix t -> Matrix t | ||
65 | ldlPacked' :: Matrix t -> (Matrix t, [Int]) | 66 | ldlPacked' :: Matrix t -> (Matrix t, [Int]) |
66 | ldlSolve' :: (Matrix t, [Int]) -> Matrix t -> Matrix t | 67 | ldlSolve' :: (Matrix t, [Int]) -> Matrix t -> Matrix t |
67 | linearSolveSVD' :: Matrix t -> Matrix t -> Matrix t | 68 | linearSolveSVD' :: Matrix t -> Matrix t -> Matrix t |
@@ -88,6 +89,7 @@ instance Field Double where | |||
88 | mbLinearSolve' = mbLinearSolveR | 89 | mbLinearSolve' = mbLinearSolveR |
89 | cholSolve' = cholSolveR | 90 | cholSolve' = cholSolveR |
90 | triSolve' = triSolveR | 91 | triSolve' = triSolveR |
92 | triDiagSolve' = triDiagSolveR | ||
91 | linearSolveLS' = linearSolveLSR | 93 | linearSolveLS' = linearSolveLSR |
92 | linearSolveSVD' = linearSolveSVDR Nothing | 94 | linearSolveSVD' = linearSolveSVDR Nothing |
93 | eig' = eigR | 95 | eig' = eigR |
@@ -118,6 +120,7 @@ instance Field (Complex Double) where | |||
118 | mbLinearSolve' = mbLinearSolveC | 120 | mbLinearSolve' = mbLinearSolveC |
119 | cholSolve' = cholSolveC | 121 | cholSolve' = cholSolveC |
120 | triSolve' = triSolveC | 122 | triSolve' = triSolveC |
123 | triDiagSolve' = triDiagSolveC | ||
121 | linearSolveLS' = linearSolveLSC | 124 | linearSolveLS' = linearSolveLSC |
122 | linearSolveSVD' = linearSolveSVDC Nothing | 125 | linearSolveSVD' = linearSolveSVDC Nothing |
123 | eig' = eigC | 126 | eig' = eigC |
@@ -356,10 +359,79 @@ cholSolve | |||
356 | -> Matrix t -- ^ solution | 359 | -> Matrix t -- ^ solution |
357 | cholSolve = {-# SCC "cholSolve" #-} cholSolve' | 360 | cholSolve = {-# SCC "cholSolve" #-} cholSolve' |
358 | 361 | ||
359 | -- | Solve a triangular linear system. | 362 | -- | Solve a triangular linear system. If `Upper` is specified then |
360 | triSolve :: Field t => UpLo -> Matrix t -> Matrix t -> Matrix t | 363 | -- all elements below the diagonal are ignored; if `Lower` is |
364 | -- specified then all elements above the diagonal are ignored. | ||
365 | triSolve | ||
366 | :: Field t | ||
367 | => UpLo -- ^ `Lower` or `Upper` | ||
368 | -> Matrix t -- ^ coefficient matrix | ||
369 | -> Matrix t -- ^ right hand sides | ||
370 | -> Matrix t -- ^ solution | ||
361 | triSolve = {-# SCC "triSolve" #-} triSolve' | 371 | triSolve = {-# SCC "triSolve" #-} triSolve' |
362 | 372 | ||
373 | -- | Solve a tridiagonal linear system. Suppose you wish to solve \(Ax = b\) where | ||
374 | -- | ||
375 | -- \[ | ||
376 | -- A = | ||
377 | -- \begin{bmatrix} | ||
378 | -- 1.0 & 4.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 | ||
379 | -- \\ 3.0 & 1.0 & 4.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 | ||
380 | -- \\ 0.0 & 3.0 & 1.0 & 4.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 | ||
381 | -- \\ 0.0 & 0.0 & 3.0 & 1.0 & 4.0 & 0.0 & 0.0 & 0.0 & 0.0 | ||
382 | -- \\ 0.0 & 0.0 & 0.0 & 3.0 & 1.0 & 4.0 & 0.0 & 0.0 & 0.0 | ||
383 | -- \\ 0.0 & 0.0 & 0.0 & 0.0 & 3.0 & 1.0 & 4.0 & 0.0 & 0.0 | ||
384 | -- \\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 3.0 & 1.0 & 4.0 & 0.0 | ||
385 | -- \\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 3.0 & 1.0 & 4.0 | ||
386 | -- \\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 3.0 & 1.0 | ||
387 | -- \end{bmatrix} | ||
388 | -- \quad | ||
389 | -- b = | ||
390 | -- \begin{bmatrix} | ||
391 | -- 1.0 & 1.0 & 1.0 | ||
392 | -- \\ 1.0 & -1.0 & 2.0 | ||
393 | -- \\ 1.0 & 1.0 & 3.0 | ||
394 | -- \\ 1.0 & -1.0 & 4.0 | ||
395 | -- \\ 1.0 & 1.0 & 5.0 | ||
396 | -- \\ 1.0 & -1.0 & 6.0 | ||
397 | -- \\ 1.0 & 1.0 & 7.0 | ||
398 | -- \\ 1.0 & -1.0 & 8.0 | ||
399 | -- \\ 1.0 & 1.0 & 9.0 | ||
400 | -- \end{bmatrix} | ||
401 | -- \] | ||
402 | -- | ||
403 | -- then | ||
404 | -- | ||
405 | -- @ | ||
406 | -- dL = fromList [3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0] | ||
407 | -- d = fromList [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] | ||
408 | -- dU = fromList [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0] | ||
409 | -- | ||
410 | -- b = (9><3) | ||
411 | -- [ | ||
412 | -- 1.0, 1.0, 1.0, | ||
413 | -- 1.0, -1.0, 2.0, | ||
414 | -- 1.0, 1.0, 3.0, | ||
415 | -- 1.0, -1.0, 4.0, | ||
416 | -- 1.0, 1.0, 5.0, | ||
417 | -- 1.0, -1.0, 6.0, | ||
418 | -- 1.0, 1.0, 7.0, | ||
419 | -- 1.0, -1.0, 8.0, | ||
420 | -- 1.0, 1.0, 9.0 | ||
421 | -- ] | ||
422 | -- | ||
423 | -- x = triDiagSolve dL d dU b | ||
424 | -- @ | ||
425 | -- | ||
426 | triDiagSolve | ||
427 | :: Field t | ||
428 | => Vector t -- ^ lower diagonal: \(n - 1\) elements | ||
429 | -> Vector t -- ^ diagonal: \(n\) elements | ||
430 | -> Vector t -- ^ upper diagonal: \(n - 1\) elements | ||
431 | -> Matrix t -- ^ right hand sides | ||
432 | -> Matrix t -- ^ solution | ||
433 | triDiagSolve = {-# SCC "triDiagSolve" #-} triDiagSolve' | ||
434 | |||
363 | -- | Minimum norm solution of a general linear least squares problem Ax=B using the SVD. Admits rank-deficient systems but it is slower than 'linearSolveLS'. The effective rank of A is determined by treating as zero those singular valures which are less than 'eps' times the largest singular value. | 435 | -- | Minimum norm solution of a general linear least squares problem Ax=B using the SVD. Admits rank-deficient systems but it is slower than 'linearSolveLS'. The effective rank of A is determined by treating as zero those singular valures which are less than 'eps' times the largest singular value. |
364 | linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t | 436 | linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t |
365 | linearSolveSVD = {-# SCC "linearSolveSVD" #-} linearSolveSVD' | 437 | linearSolveSVD = {-# SCC "linearSolveSVD" #-} linearSolveSVD' |