numeric-prelude-0.4: test/Test/MathObj/Matrix.hs
{-# 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 System.Random as Random
import Data.Function.HT (nest, )
import Test.NumericPrelude.Utility (testUnit, )
import Test.QuickCheck (Arbitrary(arbitrary), quickCheck, )
import qualified Test.QuickCheck as QC
import qualified Test.HUnit as HUnit
import NumericPrelude.Base as P
import NumericPrelude.Numeric as NP
type Seed = Int
newtype Dimension = Dimension {unDim :: Int}
deriving (Show)
instance Arbitrary Dimension where
arbitrary = fmap Dimension $ QC.choose (0,20)
random :: Dimension -> Dimension -> Seed -> Matrix.T Integer
random mn nn seed =
fst $
Matrix.random (unDim mn) (unDim nn) $
Random.mkStdGen seed
tests :: HUnit.Test
tests =
HUnit.TestLabel "matrix" $
HUnit.TestList $
map testUnit $
("dimension",
quickCheck (\m n a ->
(unDim m, unDim 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 (unDim m) (unDim n) (Matrix.rows a))) :
("to and from columns",
quickCheck (\m n a' ->
let a = random m n a'
in a == Matrix.fromColumns (unDim m) (unDim 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 (unDim m) (unDim 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 = unDim 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 (unDim m)) (random m n a))) :
("multiplication, one right",
quickCheck (\m n a ->
Laws.rightIdentity (*) (Matrix.one (unDim 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))) :
("multiplication vs. power",
quickCheck (\m a n0 ->
let x = random m m a
n = mod n0 10
in x^n == nest (fromInteger n) (x*) (Matrix.one (unDim m)))) :
{-
("division", quickCheck (\x -> Integral.propInverse (x :: Poly.T Rational))) :
-}
[]