{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
module Algebra.ModuleBasis where
import qualified Number.Ratio as Ratio
import qualified Algebra.PrincipalIdealDomain as PID
import qualified Algebra.Module as Module
import Algebra.Ring (one, fromInteger)
import Algebra.Additive ((+), zero)
import Data.List (map, length, (++))
import Prelude(Eq, (==), Bool, Int, Integer, Float, Double, asTypeOf, )
class (Module.C a v) => C a v where
basis :: a -> [v]
flatten :: v -> [a]
dimension :: a -> v -> Int
instance C Float Float where
basis _ = [one]
flatten = (:[])
dimension _ _ = 1
instance C Double Double where
basis _ = [one]
flatten = (:[])
dimension _ _ = 1
instance C Int Int where
basis _ = [one]
flatten = (:[])
dimension _ _ = 1
instance C Integer Integer where
basis _ = [one]
flatten = (:[])
dimension _ _ = 1
instance (PID.C a) => C (Ratio.T a) (Ratio.T a) where
basis _ = [one]
flatten = (:[])
dimension _ _ = 1
instance (C a v0, C a v1) => C a (v0, v1) where
basis s = map (\v -> (v,zero)) (basis s) ++
map (\v -> (zero,v)) (basis s)
flatten (x0,x1) = flatten x0 ++ flatten x1
dimension s ~(x0,x1) = dimension s x0 + dimension s x1
instance (C a v0, C a v1, C a v2) => C a (v0, v1, v2) where
basis s = map (\v -> (v,zero,zero)) (basis s) ++
map (\v -> (zero,v,zero)) (basis s) ++
map (\v -> (zero,zero,v)) (basis s)
flatten (x0,x1,x2) = flatten x0 ++ flatten x1 ++ flatten x2
dimension s ~(x0,x1,x2) = dimension s x0 + dimension s x1 + dimension s x2
propFlatten :: (Eq v, C a v) => a -> v -> Bool
propFlatten a v = Module.linearComb (flatten v `asTypeOf` [a]) (basis a) == v
propDimension :: (C a v) => a -> v -> Bool
propDimension a v = dimension a v == length (flatten v `asTypeOf` [a])