Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Matrix where
- type Matrix = [[Double]]
- isMatrixValid :: Matrix -> Bool
- isMatrixValid matrix =
- if length lenghts == 0 then
- False
- else
- (all (== head lenghts) lenghts)
- where
- lenghts = map length matrix
- newMatrix :: Matrix -> Maybe Matrix
- newMatrix matrix =
- if isMatrixValid matrix then Just matrix else Nothing
- transpose ([]:_) = []
- transpose x = (map head x) : transpose (map tail x)
- getMatrixSize :: Matrix -> (Int,Int)
- getMatrixSize matrix =
- let
- rows = length matrix
- in
- if rows == 0 then
- (0, 0)
- else
- (rows, length $ head matrix)
- sumMatrixes :: Matrix -> Matrix -> Maybe Matrix
- sumMatrixes matrix0 matrix1 =
- if getMatrixSize matrix0 /= getMatrixSize matrix1 then
- Nothing
- else
- Just $ zipWith (zipWith (+)) matrix0 matrix1
- scaleMatrix :: Double -> Matrix -> Matrix
- scaleMatrix value matrix =
- map (map (* value)) matrix
- subtractMatrixes :: Matrix -> Matrix -> Maybe Matrix
- subtractMatrixes matrix0 matrix1 =
- sumMatrixes matrix0 (scaleMatrix (-1) matrix1)
- multiplyMatrixes :: Matrix -> Matrix -> Maybe Matrix
- multiplyMatrixes matrix0 matrix1 =
- let
- size0 = getMatrixSize matrix0
- size1 = getMatrixSize matrix1
- rows = fst size0
- columns = snd size1
- in
- if snd size0 /= fst size1 then
- Nothing
- else
- Just [[ term i j | j <- [0..(columns-1)] ] | i <- [0..(rows-1)] ]
- where
- transpose1 = transpose matrix1
- term i j = sum $ zipWith (*) (matrix0 !! i) (transpose1 !! j)
- newMatrixWithValue rows columns value =
- [[ value | j <- [1..columns] ] | i <- [1..rows] ]
- pivot matrix i j =
- let
- size = getMatrixSize matrix
- filteredRows = filter (/=i) [0..(fst size - 1)]
- filteredColumns = filter (/=j) [0..(snd size - 1)]
- in
- [ let row = matrix !! i in [row !! j | j <- filteredColumns ] | i <- filteredRows ]
- cofactorSign i j =
- if (mod (i + j) 2) == 0 then 1.0 else -1.0
- determinant matrix =
- if fst size /= snd size then
- Nothing
- else
- if n == 1 then
- Just $ matrix !! 0 !! 0
- else
- if n == 2 then
- Just $ determinant2x2 matrix
- else
- Just $ determinantNxN matrix
- where
- size = getMatrixSize matrix
- n = fst size
- sign j = if (mod j 2) == 0 then 1.0 else -1.0
- determinant2x2 matrix =
- (matrix !! 0 !! 0) * (matrix !! 1 !! 1) - (matrix !! 0 !! 1) * (matrix !! 1 !! 0)
- determinantNxN matrix =
- sum [ let Just det = (determinant $ pivot matrix 0 j) in (cofactorSign 0 j) * (matrix !! 0 !! j) * det | j <- [0..n-1] ]
- cofactorsMatrix matrix =
- if fst size /= snd size then
- Nothing
- else
- Just [ [ let Just det = (determinant $ pivot matrix i j) in (cofactorSign i j) * det | j <- [0..n-1] ] | i <- [0..n-1]]
- where
- size = getMatrixSize matrix
- n = fst size
- inverse matrix =
- cofactorsMatrix matrix >>= \cofactors ->
- determinant matrix >>= \det ->
- if det == 0.0 then
- Nothing
- else
- Just $ scaleMatrix (1.0/det) (transpose cofactors)
- identity n =
- [[if i == j then 1.0 else 0.0 | j <- [0..n-1]] | i <- [0..n-1]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement