Advertisement
jckuri

Matrix.hs

Jun 9th, 2013
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Matrix where
  2.  
  3. type Matrix = [[Double]]
  4.  
  5. isMatrixValid :: Matrix -> Bool
  6. isMatrixValid matrix =
  7.  if length lenghts == 0 then
  8.   False
  9.  else
  10.   (all (== head lenghts) lenghts)
  11.  where
  12.   lenghts = map length matrix
  13.  
  14. newMatrix :: Matrix -> Maybe Matrix
  15. newMatrix matrix =
  16.  if isMatrixValid matrix then Just matrix else Nothing
  17.  
  18. transpose ([]:_) = []
  19. transpose x = (map head x) : transpose (map tail x)
  20.  
  21. getMatrixSize :: Matrix -> (Int,Int)
  22. getMatrixSize matrix =
  23.  let
  24.   rows = length matrix
  25.  in
  26.   if rows == 0 then
  27.    (0, 0)
  28.   else
  29.    (rows, length $ head matrix)
  30.  
  31. sumMatrixes :: Matrix -> Matrix -> Maybe Matrix
  32. sumMatrixes matrix0 matrix1 =
  33.  if getMatrixSize matrix0 /= getMatrixSize matrix1 then
  34.   Nothing
  35.  else
  36.   Just $ zipWith (zipWith (+)) matrix0 matrix1
  37.  
  38. scaleMatrix :: Double -> Matrix -> Matrix
  39. scaleMatrix value matrix =
  40.  map (map (* value)) matrix
  41.  
  42. subtractMatrixes :: Matrix -> Matrix -> Maybe Matrix
  43. subtractMatrixes matrix0 matrix1 =
  44.  sumMatrixes matrix0 (scaleMatrix (-1) matrix1)
  45.  
  46. multiplyMatrixes :: Matrix -> Matrix -> Maybe Matrix
  47. multiplyMatrixes matrix0 matrix1 =
  48.  let
  49.   size0 = getMatrixSize matrix0
  50.   size1 = getMatrixSize matrix1
  51.   rows = fst size0
  52.   columns = snd size1
  53.  in
  54.   if snd size0 /= fst size1 then
  55.    Nothing
  56.   else
  57.    Just [[ term i j | j <- [0..(columns-1)] ] | i <- [0..(rows-1)] ]
  58.  where
  59.   transpose1 = transpose matrix1
  60.   term i j = sum $ zipWith (*) (matrix0 !! i) (transpose1 !! j)
  61.  
  62. newMatrixWithValue rows columns value =
  63.  [[ value | j <- [1..columns] ] | i <- [1..rows] ]
  64.  
  65. pivot matrix i j =
  66.  let
  67.   size = getMatrixSize matrix
  68.   filteredRows = filter (/=i) [0..(fst size - 1)]
  69.   filteredColumns = filter (/=j) [0..(snd size - 1)]
  70.  in
  71.   [ let row = matrix !! i in [row !! j | j <- filteredColumns ] | i <- filteredRows ]
  72.  
  73. cofactorSign i j =
  74.  if (mod (i + j) 2) == 0 then 1.0 else -1.0
  75.  
  76. determinant matrix =
  77.  if fst size /= snd size then
  78.   Nothing
  79.  else
  80.   if n == 1 then
  81.    Just $ matrix !! 0 !! 0
  82.   else
  83.    if n == 2 then
  84.     Just $ determinant2x2 matrix
  85.    else
  86.     Just $ determinantNxN matrix
  87.  where
  88.   size = getMatrixSize matrix
  89.   n = fst size
  90.   sign j = if (mod j 2) == 0 then 1.0 else -1.0
  91.   determinant2x2 matrix =
  92.    (matrix !! 0 !! 0) * (matrix !! 1 !! 1) - (matrix !! 0 !! 1) * (matrix !! 1 !! 0)
  93.   determinantNxN matrix =
  94.    sum [ let Just det = (determinant $ pivot matrix 0 j) in (cofactorSign 0 j) * (matrix !! 0 !! j) * det | j <- [0..n-1] ]
  95.  
  96. cofactorsMatrix matrix =
  97.  if fst size /= snd size then
  98.   Nothing
  99.  else
  100.   Just [ [ let Just det = (determinant $ pivot matrix i j) in (cofactorSign i j) * det | j <- [0..n-1] ] | i <- [0..n-1]]
  101.  where
  102.   size = getMatrixSize matrix
  103.   n = fst size
  104.    
  105. inverse matrix =
  106.  cofactorsMatrix matrix >>= \cofactors ->
  107.  determinant matrix >>= \det ->
  108.  if det == 0.0 then
  109.   Nothing
  110.  else
  111.   Just $ scaleMatrix (1.0/det) (transpose cofactors)
  112.  
  113. identity n =
  114.  [[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