{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} module Test.MathObj.Matrix where import qualified MathObj.Matrix as Matrix import qualified Algebra.Ring as Ring import qualified Algebra.Laws as Laws import qualified Number.NonNegative as NonNeg import qualified System.Random as Random import Test.NumericPrelude.Utility (testUnit, ) import Test.QuickCheck (quickCheck, ) import qualified Test.HUnit as HUnit import PreludeBase as P import NumericPrelude as NP type Seed = Int type Dimension = NonNeg.Int random :: Dimension -> Dimension -> Seed -> Matrix.T Integer random mn nn seed = fst $ Matrix.random (NonNeg.toNumber mn) (NonNeg.toNumber nn) $ Random.mkStdGen seed tests :: HUnit.Test tests = HUnit.TestLabel "matrix" $ HUnit.TestList $ map testUnit $ ("dimension", quickCheck (\m n a -> (NonNeg.toNumber m, NonNeg.toNumber n) == Matrix.dimension (random m n a))) : ("to and from rows", quickCheck (\m n a' -> let a = random m n a' in a == Matrix.fromRows (NonNeg.toNumber m) (NonNeg.toNumber n) (Matrix.rows a))) : ("to and from columns", quickCheck (\m n a' -> let a = random m n a' in a == Matrix.fromColumns (NonNeg.toNumber m) (NonNeg.toNumber n) (Matrix.columns a))) : ("transpose, rows, columns", quickCheck (\m n a' -> let a = random m n a' in Matrix.rows a == Matrix.columns (Matrix.transpose a))) : ("transpose, columns, rows", quickCheck (\m n a' -> let a = random m n a' in Matrix.columns a == Matrix.rows (Matrix.transpose a))) : ("addition, zero", quickCheck (\m n a -> Laws.identity (+) (Matrix.zero (NonNeg.toNumber m) (NonNeg.toNumber n)) (random m n a))) : ("addition, commutative", quickCheck (\m n a b -> Laws.commutative (+) (random m n a) (random m n b))) : ("addition, associative", quickCheck (\m n a b c -> Laws.associative (+) (random m n a) (random m n b) (random m n c))) : ("addition, transpose", quickCheck (\m n a b -> Laws.homomorphism Matrix.transpose (+) (+) (random m n a) (random m n b))) : ("one, diagonal", quickCheck (\n' -> let n = NonNeg.toNumber n' in Matrix.one n == (Matrix.diagonal $ replicate n Ring.one :: Matrix.T Integer))) : ("multiplication, one left", quickCheck (\m n a -> Laws.leftIdentity (*) (Matrix.one (NonNeg.toNumber m)) (random m n a))) : ("multiplication, one right", quickCheck (\m n a -> Laws.rightIdentity (*) (Matrix.one (NonNeg.toNumber n)) (random m n a))) : ("multiplication, associative", quickCheck (\k l m n a b c -> Laws.associative (*) (random k l a) (random l m b) (random m n c))) : ("multiplication and addition, distributive left", quickCheck (\l m n a b c -> Laws.leftDistributive (*) (+) (random n l a) (random m n b) (random m n c))) : ("multiplication and addition, distributive right", quickCheck (\l m n a b c -> Laws.rightDistributive (*) (+) (random l m a) (random m n b) (random m n c))) : ("multiplication, transpose", quickCheck (\l m n a b -> Laws.homomorphism Matrix.transpose (*) (flip (*)) (random l m a) (random m n b))) : {- ("division", quickCheck (\x -> Integral.propInverse (x :: Poly.T Rational))) : -} []