sparse-linear-algebra-0.2.1.1: src/Numeric/LinearAlgebra/Class.hs
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, KindSignatures #-}
module Numeric.LinearAlgebra.Class where
-- * Additive ring
class Functor f => Additive f where
-- | Ring zero element
zero :: Num a => f a
-- | Ring +
(^+^) :: Num a => f a -> f a -> f a
one :: Num a => f a
(^*^) :: Num a => f a -> f a -> f a
-- | negate the values in a functor
negated :: (Num a, Functor f) => f a -> f a
negated = fmap negate
-- | subtract two Additive objects
(^-^) :: (Additive f, Num a) => f a -> f a -> f a
x ^-^ y = x ^+^ negated y
-- * Vector space
class Additive f => VectorSpace f where
-- | multiplication by a scalar
(.*) :: Num a => a -> f a -> f a
-- |linear interpolation
lerp :: (VectorSpace f, Num a) => a -> f a -> f a -> f a
lerp a u v = a .* u ^+^ ((1-a) .* v)
-- * Hilbert space (inner product)
class VectorSpace f => Hilbert f where
-- | inner product
dot :: Num a => f a -> f a -> a
-- ** Hilbert-space distance function
-- |`hilbertDistSq x y = || x - y ||^2`
hilbertDistSq :: (Hilbert f, Num a) => f a -> f a -> a
hilbertDistSq x y = dot t t where
t = x ^-^ y
-- * Normed vector space
class Hilbert f => Normed f where
norm :: (Floating a, Eq a) => a -> f a -> a
-- ** Norms and related results
-- | Squared 2-norm
normSq :: (Hilbert f, Num a) => f a -> a
normSq v = v `dot` v
-- |L1 norm
norm1 :: (Foldable t, Num a, Functor t) => t a -> a
norm1 v = sum (fmap abs v)
-- |Euclidean norm
norm2 :: (Hilbert f, Floating a) => f a -> a
norm2 v = sqrt (normSq v)
-- |Lp norm (p > 0)
normP :: (Foldable t, Functor t, Floating a) => a -> t a -> a
normP p v = sum u**(1/p) where
u = fmap (**p) v
-- |Infinity-norm
normInfty :: (Foldable t, Ord a) => t a -> a
normInfty = maximum
-- |Normalize w.r.t. p-norm (p finite)
normalize :: (Normed f, Floating a, Eq a) => a -> f a -> f a
normalize p v = (1 / norm p v) .* v
-- |Lp inner product (p > 0)
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
reciprocal :: (Functor f, Fractional b) => f b -> f b
reciprocal = fmap recip
-- |Scale
scale :: (Num b, Functor f) => b -> f b -> f b
scale n = fmap (* n)
-- * FiniteDim : finite-dimensional objects
class Additive f => FiniteDim f where
type FDSize f :: *
dim :: f a -> FDSize f
-- | unary dimension-checking bracket
withDim :: (FiniteDim f, Show e) =>
f a
-> (FDSize f -> f a -> Bool)
-> (f a -> c)
-> String
-> (f a -> e)
-> c
withDim x p f e ef | p (dim x) x = f x
| otherwise = error e' where e' = e ++ show (ef x)
-- | binary dimension-checking bracket
withDim2 :: (FiniteDim f, FiniteDim g, Show e) =>
f a
-> g b
-> (FDSize f -> FDSize g -> f a -> g b -> Bool)
-> (f a -> g b -> c)
-> String
-> (f a -> g b -> e)
-> c
withDim2 x y p f e ef | p (dim x) (dim y) x y = f x y
| otherwise = error e' where e' = e ++ show (ef x y)
-- * HasData : accessing inner data (do not export)
class Additive f => HasData f a where
type HDData f a :: *
dat :: f a -> HDData f a
-- * Sparse : sparse datastructures
class (FiniteDim f, HasData f a) => Sparse f a where
spy :: Fractional b => f a -> b
-- * Set : types that behave as sets
class Functor f => Set f where
-- |union binary lift : apply function on _union_ of two Sets
liftU2 :: (a -> a -> a) -> f a -> f a -> f a
-- |intersection binary lift : apply function on _intersection_ of two Sets
liftI2 :: (a -> b -> c) -> f a -> f b -> f c
class Sparse c a => SpContainer c a where
type ScIx c :: *
scInsert :: ScIx c -> a -> c a -> c a
scLookup :: c a -> ScIx c -> Maybe a
-- -- | Lookup with default, infix form ("safe" : should throw an exception if lookup is outside matrix bounds)
(@@) :: c a -> ScIx c -> a
-- * IxContainer : indexed container types
-- class IxContainer (c :: * -> *) a where
-- type Ix c :: *
-- type IxSz c :: *
-- ixcLookup :: c a -> Ix c -> Maybe a
-- ixcIfilter :: (Ix c -> a -> Bool) -> c a -> c a
-- ixcInsert :: Ix c -> a -> c a -> c a
-- ixcFromList :: Foldable t => IxSz c -> t (Ix c, a) -> c a
-- ixcToList :: c a -> [(Ix c, a)]
-- newtype IM_ a = IM (IM.IntMap a)
-- instance IxContainer IM_ a where
-- type Ix IM_ = Int
-- -- -- ixcLookupDefault = lookupDefaultSV
-- -- -- ixcFilter = filterSV
-- newtype IM2 a = IM2 { unIM2 :: IM.IntMap (IM.IntMap a)}
-- instance IxContainer IM2 a where
-- type Ix IM2 = (Int, Int)
-- ixcIfilter f im2 = IM2 $ ifilterIM2 (curry f) (unIM2 im2)
-- class Rank2 (c :: * -> *) a where
-- type R2IxRow c :: *
-- type R2IxCol c :: *
-- type R2V c :: * -> *
-- rank2Act :: c a -> R2V c a -> R2V c a
-- extractRow :: c a -> R2IxRow c -> Maybe (R2V c a)
-- extractCol :: c a -> R2IxCol c -> Maybe (R2V c a)
-- -- extractRows :: c a -> [R2IxRow c] -> [R2V c]
-- -- extractCols :: c a -> [R2IxCol c] -> [R2V c]
-- * SMatrix : sparse matrix types
-- class (IxContainer c a, Sparse c a, Additive c) => SMatrix c a where