{-# language TypeFamilies, MultiParamTypeClasses, KindSignatures, FlexibleContexts, FlexibleInstances, ConstraintKinds #-}
{-# language AllowAmbiguousTypes #-}
{-# language CPP #-}
module Numeric.LinearAlgebra.Class where
import Data.Complex
import Control.Monad.Catch
import Control.Monad.IO.Class
import qualified Data.Vector as V (Vector)
import Data.Sparse.Types
import Numeric.Eps
class (Eq e , Fractional e, Floating e, Num (EltMag e), Ord (EltMag e)) => Elt e where
type EltMag e :: *
conj :: e -> e
conj = id
mag :: e -> EltMag e
instance Elt Double where {type EltMag Double = Double ; mag = id}
instance Elt Float where {type EltMag Float = Float; mag = id}
instance (RealFloat e) => Elt (Complex e) where
type EltMag (Complex e) = e
conj = conjugate
mag = magnitude
infixl 6 ^+^, ^-^
class AdditiveGroup v where
zeroV :: v
(^+^) :: v -> v -> v
negateV :: v -> v
(^-^) :: v -> v -> v
(^-^) x y = x ^+^ negateV y
infixr 7 .*
class (AdditiveGroup v, Num (Scalar v)) => VectorSpace v where
type Scalar v :: *
(.*) :: Scalar v -> v -> v
class VectorSpace v => InnerSpace v where
(<.>) :: v -> v -> Scalar v
dot :: InnerSpace v => v -> v -> Scalar v
dot = (<.>)
infixr 7 ./
infixl 7 *.
(./) :: (VectorSpace v, s ~ Scalar v, Fractional s) => v -> s -> v
v ./ s = (recip s) .* v
(*.) :: (VectorSpace v, s ~ Scalar v) => v -> s -> v
(*.) = flip (.*)
cvx :: VectorSpace v => Scalar v -> v -> v -> v
cvx a u v = a .* u ^+^ ((1-a) .* v)
hilbertDistSq :: InnerSpace v => v -> v -> Scalar v
hilbertDistSq x y = t <.> t where
t = x ^-^ y
class (InnerSpace v, Num (RealScalar v), Eq (RealScalar v), Epsilon (Magnitude v), Show (Magnitude v), Ord (Magnitude v)) => Normed v where
type Magnitude v :: *
type RealScalar v :: *
norm1 :: v -> Magnitude v
norm2Sq :: v -> Magnitude v
normP :: RealScalar v -> v -> Magnitude v
normalize :: RealScalar v -> v -> v
normalize2 :: v -> v
normalize2' :: Floating (Scalar v) => v -> v
normalize2' x = x ./ norm2' x
norm2 :: Floating (Magnitude v) => v -> Magnitude v
norm2 x = sqrt (norm2Sq x)
norm2' :: Floating (Scalar v) => v -> Scalar v
norm2' x = sqrt $ x <.> x
norm :: Floating (Magnitude v) => RealScalar v -> v -> Magnitude v
norm p v
| p == 1 = norm1 v
| p == 2 = norm2 v
| otherwise = normP p v
normInftyR :: (Foldable t, Ord a) => t a -> a
normInftyR x = maximum x
normInftyC :: (Foldable t, RealFloat a, Functor t) => t (Complex a) -> a
normInftyC x = maximum (magnitude <$> x)
dotLp :: (Set t, Foldable t, Floating a) => a -> t a -> t a -> a
dotLp p v1 v2 = sum u**(1/p) where
f a b = (a*b)**p
u = liftI2 f v1 v2
reciprocal :: (Functor f, Fractional b) => f b -> f b
reciprocal = fmap recip
scale :: (Num b, Functor f) => b -> f b -> f b
scale n = fmap (* n)
class (AdditiveGroup m, Epsilon (MatrixNorm m)) => MatrixRing m where
type MatrixNorm m :: *
(##) :: m -> m -> m
(##^) :: m -> m -> m
(#^#) :: m -> m -> m
a #^# b = transpose a ## b
transpose :: m -> m
normFrobenius :: m -> MatrixNorm m
class (VectorSpace v ) => LinearVectorSpace v where
type MatrixType v :: *
(#>) :: MatrixType v -> v -> v
(<#) :: v -> MatrixType v -> v
type V v = (LinearVectorSpace v, Normed v)
class LinearVectorSpace v => LinearSystem v where
(<\>) :: (MonadIO m, MonadThrow m) =>
MatrixType v
-> v
-> m v
class FiniteDim f where
type FDSize f
dim :: f -> FDSize f
class HasData f where
type HDData f
nnz :: f -> Int
dat :: f -> HDData f
class (FiniteDim f, HasData f) => Sparse f where
spy :: Fractional b => f -> b
class Functor f => Set f where
liftU2 :: (a -> a -> a) -> f a -> f a -> f a
liftI2 :: (a -> a -> b) -> f a -> f a -> f b
class Sparse c => SpContainer c where
type ScIx c :: *
type ScElem c
scInsert :: ScIx c -> ScElem c -> c -> c
scLookup :: c -> ScIx c -> Maybe (ScElem c)
scToList :: c -> [(ScIx c, ScElem c)]
(@@) :: c -> ScIx c -> ScElem c
class SpContainer v => SparseVector v where
type SpvIx v :: *
svFromList :: Int -> [(SpvIx v, ScElem v)] -> v
svFromListDense :: Int -> [ScElem v] -> v
svConcat :: Foldable t => t v -> v
class SpContainer m => SparseMatrix m where
smFromVector :: LexOrd -> (Int, Int) -> V.Vector (IxRow, IxCol, ScElem m) -> m
smTranspose :: m -> m
encodeIx :: m -> LexOrd -> (IxRow, IxCol) -> LexIx
decodeIx :: m -> LexOrd -> LexIx -> (IxRow, IxCol)
toC :: Num a => a -> Complex a
toC r = r :+ 0
#define ScalarType(t) \
instance AdditiveGroup (t) where {zeroV = 0; (^+^) = (+); negateV = negate};\
instance VectorSpace (t) where {type Scalar (t) = t; (.*) = (*) };
ScalarType(Float)
ScalarType(Double)
ScalarType(Complex Float)
ScalarType(Complex Double)
#undef ScalarType
instance InnerSpace Float where {(<.>) = (*)}
instance InnerSpace Double where {(<.>) = (*)}
instance InnerSpace (Complex Float) where {x <.> y = x * conjugate y}
instance InnerSpace (Complex Double) where {x <.> y = x * conjugate y}
#define SimpleNormedInstance(t) \
instance Normed (t) where {type Magnitude (t) = t; type RealScalar (t) = t;\
norm1 = abs; norm2Sq = (**2); normP _ = abs; normalize _ = signum;\
normalize2 = signum; normalize2' = signum; norm2 = abs; norm2' = abs; norm _ = abs};
SimpleNormedInstance(Float)
SimpleNormedInstance(Double)
#undef SimpleNormedInstance
#define ComplexNormedInstance(t) \
instance Normed (Complex (t)) where {\
type Magnitude (Complex (t)) = t;\
type RealScalar (Complex (t)) = t;\
norm1 (r :+ i) = abs r + abs i;\
norm2Sq (r :+ i) = r*r + i*i;\
normP p (r :+ i) = (r**p + i**p)**(1/p);\
normalize p c = toC (1 / normP p c) * c;\
normalize2 c = (1 / norm2' c) * c;\
norm2 = magnitude;\
norm2' = toC . magnitude;};
ComplexNormedInstance(Float)
ComplexNormedInstance(Double)
#undef ComplexNormedInstance