{-# language FlexibleContexts, RecordWildCards #-}
module Data.Sparse.PPrint (prd, prd0, PrintDense, newline
, PPrintOptions(..)
, printDN , printCN
) where
import Data.Complex
import Data.List
import Text.Printf
import Numeric.Eps
class PrintDense a where
prd :: a -> IO ()
prd0 :: a -> IO ()
newline :: IO ()
newline = putStrLn ""
data PPrintOptions =
PPOpts {
pprintLen, pprintDec, pprintColWidth :: Int
} deriving (Eq, Show)
prdefR, prdefC :: PPrintOptions
prdefR = PPOpts 4 2 7
prdefC = PPOpts 4 2 16
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 "_"
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 "_"
printNpad ::
Int
-> 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-2 || llen>=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 = " ... "
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]
nl = pprintLen
nd = pprintDec
nint = nl - nd
magLo = 10 ** (- fromIntegral nd)
magHi = 10 ** fromIntegral nint
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
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