module System.Console.Ansigraph.Internal.Matrix ( matShow , displayMat , displayCMat ) where import System.Console.Ansigraph.Internal.Core import Data.Complex ---- Matrices ---- mmap :: (a -> b) -> [[a]] -> [[b]] mmap = map . map mmax :: (Num a, Ord a) => [[a]] -> a mmax = maximum . map maximum . mmap abs densityChars = "█▓▒░" densityVals :: [Double] densityVals = (+ 0.125) . (/4) <$> [3,2,1,0] -- = [7/8, 5/8, 3/8, 1/8] blocks, blocksR :: [(Double,Char)] blocks = zipWith (,) densityVals densityChars blocksR = zipWith (,) densityVals (reverse densityChars) selectBlock :: Double -> Char selectBlock x = let l = filter (\p -> fst p < abs x) blocks in case l of [] -> ' ' (p:ss) -> snd p -- | Given a matrix of Doubles, return the list of strings illustrating the absolute value -- of each entry relative to the largest, via unicode chars that denote a particular density. matShow :: [[Double]] -> [String] matShow m = let mx = mmax m in mmap (selectBlock . (/ mx)) m -- | Use ANSI coloring (specified by an 'AGSettings') to visually display a Real matrix. displayMat :: AGSettings -> [[Double]] -> IO () displayMat s m = withColoring (realColors s) . mapM_ putStrLn $ matShow m -- | Use ANSI coloring (specified by an 'AGSettings') to visually display a Complex matrix. displayCMat :: AGSettings -> [[Complex Double]] -> IO () displayCMat s m = displayMat s $ mmap magnitude m