import Data.Vector.Fixed (
(!),
generate,
+ mk0,
mk1,
mk2,
mk3,
mk5 )
import qualified Data.Vector.Fixed as V (
and,
+ foldl,
fromList,
head,
ifoldl,
ifoldr,
imap,
map,
- maximum,
replicate,
reverse,
toList,
import Naturals
import Normed ( Normed(..) )
-import NumericPrelude hiding ( (*), abs )
+-- We want the "max" that works on Ord, not the one that only works on
+-- Bool/Integer from the Lattice class!
+import NumericPrelude hiding ( (*), abs, max)
import qualified NumericPrelude as NP ( (*) )
import qualified Algebra.Absolute as Absolute ( C )
import Algebra.Absolute ( abs )
import qualified Algebra.RealRing as RealRing ( C )
import qualified Algebra.ToRational as ToRational ( C )
import qualified Algebra.Transcendental as Transcendental ( C )
-import qualified Prelude as P ( map )
+import qualified Prelude as P ( map, max)
-- | Our main matrix type.
data Mat m n a = (Arity m, Arity n) => Mat (Vec m (Vec n a))
-- Type synonyms for n-by-n matrices.
+type Mat0 a = Mat Z Z a
type Mat1 a = Mat N1 N1 a
type Mat2 a = Mat N2 N2 a
type Mat3 a = Mat N3 N3 a
-- | Type synonym for column vectors expressed as n-by-1 matrices.
type Col n a = Mat n N1 a
+type Col0 a = Col Z a
type Col1 a = Col N1 a
type Col2 a = Col N2 a
type Col3 a = Col N3 a
-- >>> frobenius_norm (r - (transpose expected)) < 1e-12
-- True
--
-cholesky :: forall m n a. (Algebraic.C a, Arity m, Arity n)
- => (Mat m n a) -> (Mat m n a)
-cholesky m = construct r
+cholesky :: forall m a. (Algebraic.C a, Arity m)
+ => (Mat m m a) -> (Mat m m a)
+cholesky m = ifoldl2 f zero m
where
- r :: Int -> Int -> a
- r i j | i == j = sqrt(m !!! (i,j) - sum [(r k i)^2 | k <- [0..i-1]])
- | i < j =
- (((m !!! (i,j)) - sum [(r k i) NP.* (r k j) | k <- [0..i-1]]))/(r i i)
- | otherwise = 0
+ f :: Int -> Int -> (Mat m m a) -> a -> (Mat m m a)
+ f i j cur_R _ = set_idx cur_R (i,j) (r cur_R i j)
+
+ r :: (Mat m m a) -> Int -> Int -> a
+ r cur_R i j
+ | i == j = sqrt(m !!! (i,j) - sum [(cur_R !!! (k,i))^2 | k <- [0..i-1]])
+ | i < j = (((m !!! (i,j))
+ - sum [(cur_R !!! (k,i)) NP.* (cur_R !!! (k,j))
+ | k <- [0..i-1]]))/(cur_R !!! (i,i))
+ | otherwise = 0
+
-- | Returns True if the given matrix is upper-triangular, and False
instance (Ring.C a, Arity m, Arity n, m ~ n) => Ring.C (Mat (S m) (S n) a) where
-- The first * is ring multiplication, the second is matrix
-- multiplication.
+ one = identity_matrix
m1 * m2 = m1 * m2
Algebraic.C a,
ToRational.C a,
Arity m)
- => Normed (Col (S m) a) where
- -- | Generic p-norms for vectors in R^n that are represented as n-by-1
+ => Normed (Col m a) where
+ -- | Generic p-norms for vectors in R^m that are represented as m-by-1
-- matrices.
--
-- Examples:
-- >>> norm_p 1 v1 :: Double
-- 2.0
--
+ -- >>> let v1 = vec0d :: Col0 Double
+ -- >>> norm v1
+ -- 0.0
+ --
norm_p p (Mat rows) =
(root p') $ sum [fromRational' (toRational $ abs x)^p' | x <- xs]
where
-- 5
--
norm_infty (Mat rows) =
- fromRational' $ toRational $ V.maximum $ V.map V.maximum rows
+ fromRational' $ toRational
+ $ (V.foldl P.max 0) $ V.map (V.foldl P.max 0) rows
-- | Compute the Frobenius norm of a matrix. This essentially treats
-- >>> fixed_point g eps u0
-- ((1.0728549599342185),(1.0820591495686167))
--
+vec0d :: Col0 a
+vec0d = Mat mk0
+
vec1d :: (a) -> Col1 a
vec1d (x) = Mat (mk1 (mk1 x))