mult:: Num a => [[a]] -> [[a]] -> [[a]] mult uss vss = map ((\xs -> if null xs then [] else foldl1 (zipWith (+)) xs). zipWith (\vs u -> map (u*) vs) vss) uss bubble::([a] -> c) -> (c -> c -> Bool) -> [[a]] -> [[b]] -> ([[a]],[[b]]) bubble _ _ [] ts = ([],ts) bubble _ _ rs [] = (rs,[]) bubble f g (r:rs) (t:ts) = bub r t (f r) rs ts [] [] where bub l k _ [] _ xs ys = (l:xs,k:ys) bub l k _ _ [] xs ys = (l:xs,k:ys) bub l k m (u:us) (v:vs) xs ys = ans where mu = f u ans | g m mu = bub l k m us vs (u:xs) (v:ys) | otherwise = bub u v mu us vs (l:xs) (k:ys) pivot::Num a => [a] -> [a] -> [[a]] -> [[a]] -> ([[a]],[[a]]) pivot xs ks ys ls = go ys ls [] [] where x = head xs fun r = zipWith (\u v -> u*r - v*x) val rs ts = let f = fun (head rs) in (tail $ f xs rs,f ks ts) go [] _ us vs = (us,vs) go _ [] us vs = (us,vs) go rs ts us vs = go (tail rs) (tail ts) (es:us) (fs:vs) where (es,fs) = val (head rs) (head ts) triangle::(Num a,Ord a) => [[a]] -> [[a]] -> ([[a]],[[a]]) triangle as bs = go (as,bs) [] [] where go ([],_) us vs = (us,vs) go (_,[]) us vs = (us,vs) go (rs,ts) us vs = ans where (xs:ys,ks:ls) = bubble (abs.head) (>=) rs ts ans = go (pivot xs ks ys ls) (xs:us) (ks:vs) solveTriangle::(Fractional a,Eq a) => [[a]] -> [[a]] -> [[a]] solveTriangle [] _ = [] solveTriangle _ [] = [] solveTriangle as _ | not.null.dropWhile ((/= 0).head) $ as = [] solveTriangle ([c]:as) (b:bs) = go as bs [map (/c) b] where val us vs ws = let u = head us in map (/u) $ zipWith (-) vs (head $ mult [tail us] ws) go [] _ zs = zs go _ [] zs = zs go (x:xs) (y:ys) zs = go xs ys $ (val x y zs):zs solveGauss:: (Fractional a, Ord a) => [[a]] -> [[a]] -> [[a]] solveGauss as bs = uncurry solveTriangle $ triangle as bs matI::(Num a) => Int -> [[a]] matI n = [ [fromIntegral.fromEnum $ i == j | j <- [1..n]] | i <- [1..n]] task::[[Rational]] -> [[Rational]] -> IO() task a b = do let x = solveGauss a b let u = map (map fromRational) x let y = mult a x let identity = matI (length x) let a1 = solveGauss a identity let h = mult a a1 let z = mult a1 b putStrLn "a =" mapM_ print a putStrLn "b =" mapM_ print b putStrLn "solve: a * x = b => x = solveGauss a b =" mapM_ print x putStrLn "u = fromRationaltoDouble x =" mapM_ print u putStrLn "verification: y = a * x = mult a x =" mapM_ print y putStrLn $ "test: y == b = " print $ y == b putStrLn "identity matrix: identity =" mapM_ print identity putStrLn "find: a1 = inv(a) => solve: a * a1 = identity => a1 = solveGauss a identity =" mapM_ print a1 putStrLn "verification: h = a * a1 = mult a a1 =" mapM_ print h putStrLn $ "test: h == identity = " print $ h == identity putStrLn "z = a1 * b = mult a1 b =" mapM_ print z putStrLn "test: z == x =" print $ z == x main = do let a = [[1.00, 0.00, 0.00, 0.00, 0.00, 0.00], [1.00, 0.63, 0.39, 0.25, 0.16, 0.10], [1.00, 1.26, 1.58, 1.98, 2.49, 3.13], [1.00, 1.88, 3.55, 6.70, 12.62, 23.80], [1.00, 2.51, 6.32, 15.88, 39.90, 100.28], [1.00, 3.14, 9.87, 31.01, 97.41, 306.02]] let b = [[-0.01], [0.61], [0.91], [0.99], [0.60], [0.02]] task a b