type Number = Rational type Vector = [Number] type Row = [Number] type Matrix = [Row] gauss :: Matrix -> Vector -> Vector gauss a b = resubstitute $ triangular $ zipWith (++) a $ map (\y -> [y]) b triangular :: Matrix -> Matrix triangular [] = [] triangular m = row:(triangular $ map f rows) where (row:rows) = rotatePivot m rotatePivot (row:rows) | (head row) /= 0 = (row:rows) | otherwise = rotatePivot (rows ++ [row]) f bs | (head bs) == 0 = drop 1 bs | otherwise = drop 1 $ zipWith (-) (map (*c) bs) row where c = (head row)/(head bs) resubstitute :: Matrix -> Vector resubstitute = reverse . resubstitute' . reverse . map reverse where resubstitute' [] = [] resubstitute' (row:rows) = x:(resubstitute' $ map substituteUnknown rows) where x = (head row)/(last row) substituteUnknown (a1:(a2:as')) = ((a1-x*a2):as') m1 = [[1,1,0], [0,1,1], [1,0,1]] :: Matrix v1 = [2,3,4] :: Vector main = print $ gauss m1 v1