summaryrefslogtreecommitdiff
path: root/lib/Numeric/LinearAlgebra/Algorithms.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Numeric/LinearAlgebra/Algorithms.hs')
-rw-r--r--lib/Numeric/LinearAlgebra/Algorithms.hs73
1 files changed, 47 insertions, 26 deletions
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs
index 0f3ff0e..28063a9 100644
--- a/lib/Numeric/LinearAlgebra/Algorithms.hs
+++ b/lib/Numeric/LinearAlgebra/Algorithms.hs
@@ -61,9 +61,10 @@ module Numeric.LinearAlgebra.Algorithms (
61 nullspacePrec, 61 nullspacePrec,
62 nullVector, 62 nullVector,
63 nullspaceSVD, 63 nullspaceSVD,
64-- * Norms
65 Normed(..), NormType(..),
64-- * Misc 66-- * Misc
65 eps, peps, i, 67 eps, peps, i,
66 Normed(..), NormType(..),
67-- * Util 68-- * Util
68 haussholder, 69 haussholder,
69 unpackQR, unpackHess, 70 unpackQR, unpackHess,
@@ -172,9 +173,6 @@ thinSVD = {-# SCC "thinSVD" #-} thinSVD'
172singularValues :: Field t => Matrix t -> Vector Double 173singularValues :: Field t => Matrix t -> Vector Double
173singularValues = {-# SCC "singularValues" #-} sv' 174singularValues = {-# SCC "singularValues" #-} sv'
174 175
175instance (Field t, RealOf t ~ Double) => Norm2 Matrix t where
176 norm2 m = singularValues m @> 0
177
178-- | A version of 'svd' which returns an appropriate diagonal matrix with the singular values. 176-- | A version of 'svd' which returns an appropriate diagonal matrix with the singular values.
179-- 177--
180-- If @(u,d,v) = fullSVD m@ then @m == u \<> d \<> trans v@. 178-- If @(u,d,v) = fullSVD m@ then @m == u \<> d \<> trans v@.
@@ -546,7 +544,7 @@ epslist = [ (fromIntegral k, golubeps k k) | k <- [1..]]
546geps delta = head [ k | (k,g) <- epslist, g<delta] 544geps delta = head [ k | (k,g) <- epslist, g<delta]
547 545
548expGolub m = iterate msq f !! j 546expGolub m = iterate msq f !! j
549 where j = max 0 $ floor $ log2 $ normInf m 547 where j = max 0 $ floor $ log2 $ pnorm Infinity m
550 log2 x = log x / log 2 548 log2 x = log x / log 2
551 a = m */ fromIntegral ((2::Int)^j) 549 a = m */ fromIntegral ((2::Int)^j)
552 q = geps eps -- 7 steps 550 q = geps eps -- 7 steps
@@ -569,7 +567,7 @@ expGolub m = iterate msq f !! j
569{- | Matrix exponential. It uses a direct translation of Algorithm 11.3.1 in Golub & Van Loan, 567{- | Matrix exponential. It uses a direct translation of Algorithm 11.3.1 in Golub & Van Loan,
570 based on a scaled Pade approximation. 568 based on a scaled Pade approximation.
571-} 569-}
572expm :: (Norm Vector t, Field t) => Matrix t -> Matrix t 570expm :: (Normed (Matrix t), Field t) => Matrix t -> Matrix t
573expm = expGolub 571expm = expGolub
574 572
575-------------------------------------------------------------- 573--------------------------------------------------------------
@@ -585,11 +583,11 @@ It only works with invertible matrices that have a real solution. For diagonaliz
585 [ 2.0, 2.25 583 [ 2.0, 2.25
586 , 0.0, 2.0 ]@ 584 , 0.0, 2.0 ]@
587-} 585-}
588sqrtm :: (Norm Vector t, Field t) => Matrix t -> Matrix t 586sqrtm :: (Normed (Matrix t), Field t) => Matrix t -> Matrix t
589sqrtm = sqrtmInv 587sqrtm = sqrtmInv
590 588
591sqrtmInv x = fst $ fixedPoint $ iterate f (x, ident (rows x)) 589sqrtmInv x = fst $ fixedPoint $ iterate f (x, ident (rows x))
592 where fixedPoint (a:b:rest) | norm1 (fst a |-| fst b) < peps = a 590 where fixedPoint (a:b:rest) | pnorm PNorm1 (fst a |-| fst b) < peps = a
593 | otherwise = fixedPoint (b:rest) 591 | otherwise = fixedPoint (b:rest)
594 fixedPoint _ = error "fixedpoint with impossible inputs" 592 fixedPoint _ = error "fixedpoint with impossible inputs"
595 f (y,z) = (0.5 .* (y |+| inv z), 593 f (y,z) = (0.5 .* (y |+| inv z),
@@ -632,33 +630,56 @@ luFact (l_u,perm) | r <= c = (l ,u ,p, s)
632 630
633--------------------------------------------------------------------------- 631---------------------------------------------------------------------------
634 632
635data NormType = Infinity | PNorm1 | PNorm2 633data NormType = Infinity | PNorm1 | PNorm2 | Frobenius
636 634
637-- | Old class
638class Normed t where 635class Normed t where
639 pnorm :: NormType -> t -> Double 636 pnorm :: NormType -> t -> Double
640 637
641instance Norm Vector t => Normed (Vector t) where 638instance Normed (Vector Double) where
642 pnorm PNorm1 = realToFrac . norm1 639 pnorm PNorm1 = norm1
643 pnorm PNorm2 = realToFrac . normFrob 640 pnorm PNorm2 = norm2
644 pnorm Infinity = realToFrac . normInf 641 pnorm Infinity = normInf
642 pnorm Frobenius = normInf
643
644instance Normed (Vector (Complex Double)) where
645 pnorm PNorm1 = realPart . norm1
646 pnorm PNorm2 = realPart . norm2
647 pnorm Infinity = realPart . normInf
648 pnorm Frobenius = realPart . normInf
649
650instance Normed (Vector Float) where
651 pnorm PNorm1 = realToFrac . norm1
652 pnorm PNorm2 = realToFrac . norm2
653 pnorm Infinity = realToFrac . normInf
654 pnorm Frobenius = realToFrac . normInf
655
656instance Normed (Vector (Complex Float)) where
657 pnorm PNorm1 = realToFrac . realPart . norm1
658 pnorm PNorm2 = realToFrac . realPart . norm2
659 pnorm Infinity = realToFrac . realPart . normInf
660 pnorm Frobenius = realToFrac . realPart . normInf
661
645 662
646instance Normed (Matrix Double) where 663instance Normed (Matrix Double) where
647 pnorm PNorm1 = norm1 664 pnorm PNorm1 = maximum . map norm1 . toColumns
648 pnorm PNorm2 = norm2 665 pnorm PNorm2 = (@>0) . singularValues
649 pnorm Infinity = normInf 666 pnorm Infinity = pnorm PNorm1 . trans
667 pnorm Frobenius = norm2 . flatten
650 668
651instance Normed (Matrix (Complex Double)) where 669instance Normed (Matrix (Complex Double)) where
652 pnorm PNorm1 = norm1 670 pnorm PNorm1 = maximum . map (realPart.norm1) . toColumns
653 pnorm PNorm2 = norm2 671 pnorm PNorm2 = (@>0) . singularValues
654 pnorm Infinity = normInf 672 pnorm Infinity = pnorm PNorm1 . trans
673 pnorm Frobenius = realPart . norm2 . flatten
655 674
656instance Normed (Matrix Float) where 675instance Normed (Matrix Float) where
657 pnorm PNorm1 = realToFrac . norm1 676 pnorm PNorm1 = realToFrac . maximum . map norm1 . toColumns
658 pnorm PNorm2 = norm2 . double -- not yet optimized for Float 677 pnorm PNorm2 = realToFrac . (@>0) . singularValues . double
659 pnorm Infinity = realToFrac . normInf 678 pnorm Infinity = realToFrac . pnorm PNorm1 . trans
679 pnorm Frobenius = realToFrac . norm2 . flatten
660 680
661instance Normed (Matrix (Complex Float)) where 681instance Normed (Matrix (Complex Float)) where
662 pnorm PNorm1 = realToFrac . norm1 682 pnorm PNorm1 = realToFrac . maximum . map (realPart.norm1) . toColumns
663 pnorm PNorm2 = norm2 . double -- not yet optimized for Float 683 pnorm PNorm2 = realToFrac . (@>0) . singularValues . double
664 pnorm Infinity = realToFrac . normInf 684 pnorm Infinity = realToFrac . pnorm PNorm1 . trans
685 pnorm Frobenius = realToFrac . realPart . norm2 . flatten