{-# language FlexibleContexts, RecordWildCards #-} ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2016 Marco Zocca -- License : GPL-3 (see LICENSE) -- Maintainer : zocca.marco gmail -- Stability : provisional -- Portability : portable -- -- -- Pretty printing helper functions ----------------------------------------------------------------------------- module Data.Sparse.PPrint (prd, prd0, PrintDense, newline , PPrintOptions(..) -- , prdefR, prdefC , printDN , printCN ) where import Data.Complex import Data.List import Text.Printf import Numeric.Eps class PrintDense a where -- | Pretty-print with a descriptive header prd :: a -> IO () -- | Pretty-print with no header prd0 :: a -> IO () newline :: IO () newline = putStrLn "" -- | Pretty printing options: total length in # digits (including the decimal point), # of decimal digits data PPrintOptions = PPOpts { pprintLen, pprintDec, pprintColWidth :: Int } deriving (Eq, Show) -- | Some defaults prdefR, prdefC :: PPrintOptions prdefR = PPOpts 4 2 7 -- reals prdefC = PPOpts 4 2 16 -- complex values -- | Pretty print an array of real numbers printDN :: (PrintfArg a, Epsilon a, Ord a) => Int -> Int -> PPrintOptions -> [a] -> String printDN l n = printNpad l n f where f o x | isNz x = printf (prepD o x) x | otherwise = printf "_" -- | Pretty print an array of complex numbers printCN :: (PrintfArg a, Epsilon a, Epsilon (Complex a), Ord a) => Int -> Int -> PPrintOptions -> [Complex a] -> String printCN l n = printNpad l n f where f o x | nearZero (re x) && isNz (imagPart x) = printf (prepD o (imagPart x)++ "i") (aim x) | nearZero (imagPart x) && isNz (re x) = printf (prepD o (realPart x)) (re x) | isNz x = printf (prepC o x) (re x) (aim x) | otherwise = printf "_" -- | printf an array of items with padding space to render a fixed column width printNpad :: Int -- ^ Length of list to be provided -> Int -- ^ -> (PPrintOptions -> a -> String) -> PPrintOptions -> [a] -> String printNpad llen nmax f o@PPOpts{..} xxl = commas [h,l] where h = commas $ take hlen ll l = last ll hlen = min (llen-1) (nmax-1) ll = unfoldr g (0, xxl) g (i, x:xs) | i=nmax-1 = Just (s', sxs) | i==nmax-2 = Just (dots', sxs) | null xs = Just (s', sxs) | otherwise = Just ("", sxs) where s = f o x sxs = (succ i, xs) s' = s ++ spaces (n - length s) dots' = dots ++ spaces (n - length dots) g (_, []) = Nothing n = pprintColWidth dots = " ... " -- | printf format string prepD :: (Ord t, Epsilon t) => PPrintOptions -> t -> String prepD PPOpts{..} x = s where s | nearZero x = "_" | abs x > magHi || abs x < magLo = s0 ++ "e" | otherwise = s0 ++ "f" s0 = concat ["%" , show nl, ".", show nd] -- s0 = "%1." ++ show nd nl = pprintLen nd = pprintDec nint = nl - nd -- # of integer digits magLo = 10 ** (- fromIntegral nd) magHi = 10 ** fromIntegral nint -- | printf format string for a Complex prepC :: (Epsilon t, Ord t) => PPrintOptions -> Complex t -> String prepC opts (r :+ i) = prepD opts r ++ oi where oi = concat [s, prepD opts i', "i"] s | signum i >= 0 = " + " | otherwise = " - " i' = abs i -- | Helpers spaces :: Int -> String spaces n = replicate n ' ' commas :: [String] -> String commas = intercalate ", " re :: Complex a -> a re = realPart aim :: Num a => Complex a -> a aim = abs . imagPart