import Ratio
gaussStep :: [[Rational]] -> [[Rational]]
gaussStep (x:xs) = x : (map (\l -> zipWith (\a b -> b - (head l) * a) (map (/ head x) x) l) xs)
findAndReplace :: (a -> Bool) -> a -> [a] -> [a] -> [a]
findAndReplace p l (x:xs) result
| p x = x : result ++ [l] ++ xs
| otherwise = findAndReplace p l xs $ result ++ [x]
gaussSwap :: [[Rational]] -> [[Rational]]
gaussSwap (x:xs) = findAndReplace (\x -> head x /= 0) x xs []
rationalGaussDet :: [[Rational]] -> Rational
rationalGaussDet [[]] = 0
rationalGaussDet [[x]] = x
rationalGaussDet m@(x:xs)
| map head m == replicate (length m) 0 = 0
| head x == 0 = (toRational 0) - (rationalGaussDet $ gaussSwap m)
| otherwise = (head x) * rationalGaussDet (minor 0 (gaussStep m))
gaussDet :: (Real a) => [[a]] -> Rational
gaussDet m = rationalGaussDet (map (map toRational) m)
Comments