45 lines
1.8 KiB
Haskell
45 lines
1.8 KiB
Haskell
import Data.List (transpose)
|
|
import Data.Complex
|
|
|
|
type Matrix a = [[a]]
|
|
|
|
main :: IO ()
|
|
main =
|
|
mapM_ (\a -> do
|
|
putStrLn "\nMatrix:"
|
|
mapM_ print a
|
|
putStrLn "Conjugate Transpose:"
|
|
mapM_ print (conjTranspose a)
|
|
putStrLn $ "Hermitian? " ++ show (isHermitianMatrix a)
|
|
putStrLn $ "Normal? " ++ show (isNormalMatrix a)
|
|
putStrLn $ "Unitary? " ++ show (isUnitaryMatrix a))
|
|
([[[3, 2:+1],
|
|
[2:+(-1), 1 ]],
|
|
|
|
[[1, 1, 0],
|
|
[0, 1, 1],
|
|
[1, 0, 1]],
|
|
|
|
[[sqrt 2/2:+0, sqrt 2/2:+0, 0 ],
|
|
[0:+sqrt 2/2, 0:+ (-sqrt 2/2), 0 ],
|
|
[0, 0, 0:+1]]] :: [Matrix (Complex Double)])
|
|
|
|
isHermitianMatrix, isNormalMatrix, isUnitaryMatrix :: RealFloat a => Matrix (Complex a) -> Bool
|
|
isHermitianMatrix a = a `approxEqualMatrix` conjTranspose a
|
|
isNormalMatrix a = (a `mmul` conjTranspose a) `approxEqualMatrix` (conjTranspose a `mmul` a)
|
|
isUnitaryMatrix a = (a `mmul` conjTranspose a) `approxEqualMatrix` ident (length a)
|
|
|
|
approxEqualMatrix :: (Fractional a, Ord a) => Matrix (Complex a) -> Matrix (Complex a) -> Bool
|
|
approxEqualMatrix a b = length a == length b && length (head a) == length (head b) &&
|
|
and (zipWith approxEqualComplex (concat a) (concat b))
|
|
where approxEqualComplex (rx :+ ix) (ry :+ iy) = abs (rx - ry) < eps && abs (ix - iy) < eps
|
|
eps = 1e-14
|
|
|
|
mmul :: Num a => Matrix a -> Matrix a -> Matrix a
|
|
mmul a b = [[sum (zipWith (*) row column) | column <- transpose b] | row <- a]
|
|
|
|
ident :: Num a => Int -> Matrix a
|
|
ident size = [[fromIntegral $ div a b * div b a | a <- [1..size]] | b <- [1..size]]
|
|
|
|
conjTranspose :: Num a => Matrix (Complex a) -> Matrix (Complex a)
|
|
conjTranspose = map (map conjugate) . transpose
|