    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Internal.IO
    -- Copyright   :  (c) Alberto Ruiz 2010
    -- License     :  BSD3
    --
    -- Maintainer  :  Alberto Ruiz
    -- Stability   :  provisional
    --
    -- Display, formatting and IO functions for numeric 'Vector' and 'Matrix'
    --
    -----------------------------------------------------------------------------

    module Internal.IO (
        dispf, disps, dispcf, vecdisp, latexFormat, format,
        loadMatrix, loadMatrix', saveMatrix
    ) where

    import Internal.Devel
    import Internal.Vector
    import Internal.Matrix
    import Internal.Vectorized
    import Text.Printf(printf, PrintfArg, PrintfType)
    import Data.List(intersperse,transpose)
    import Data.Complex

    -- | Formatting tool
    table :: String -> [[String]] -> String
    table :: FilePath -> [[FilePath]] -> FilePath
    table FilePath
    sep [[FilePath]]
    as = [FilePath] -> FilePath
    unlines ([FilePath] -> FilePath)
    -> ([[FilePath]] -> [FilePath]) -> [[FilePath]] -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([FilePath] -> FilePath) -> [[FilePath]] -> [FilePath]
    forall a b. (a -> b) -> [a] -> [b]
    map [FilePath] -> FilePath
    unwords' ([[FilePath]] -> FilePath) -> [[FilePath]] -> FilePath
    forall a b. (a -> b) -> a -> b
    $ [[FilePath]] -> [[FilePath]]
    forall a. [[a]] -> [[a]]
    transpose [[FilePath]]
    mtp
      where
        mt :: [[FilePath]]
    mt = [[FilePath]] -> [[FilePath]]
    forall a. [[a]] -> [[a]]
    transpose [[FilePath]]
    as
        longs :: [Int]
    longs = ([FilePath] -> Int) -> [[FilePath]] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Int] -> Int
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum ([Int] -> Int) -> ([FilePath] -> [Int]) -> [FilePath] -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FilePath -> Int) -> [FilePath] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map FilePath -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length) [[FilePath]]
    mt
        mtp :: [[FilePath]]
    mtp = (Int -> [FilePath] -> [FilePath])
    -> [Int] -> [[FilePath]] -> [[FilePath]]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\Int
    a [FilePath]
    b -> (FilePath -> FilePath) -> [FilePath] -> [FilePath]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> FilePath -> FilePath
    pad Int
    a) [FilePath]
    b) [Int]
    longs [[FilePath]]
    mt
        pad :: Int -> FilePath -> FilePath
    pad Int
    n FilePath
    str = Int -> Char -> FilePath
    forall a. Int -> a -> [a]
    replicate (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - FilePath -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length FilePath
    str) Char
    ' ' FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    str
        unwords' :: [FilePath] -> FilePath
    unwords' = [FilePath] -> FilePath
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([FilePath] -> FilePath)
    -> ([FilePath] -> [FilePath]) -> [FilePath] -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath] -> [FilePath]
    forall a. a -> [a] -> [a]
    intersperse FilePath
    sep

    {- | Creates a string from a matrix given a separator and a function to show each entry. Using
    this function the user can easily define any desired display function:

    @import Text.Printf(printf)@

    @disp = putStr . format \"  \" (printf \"%.2f\")@

    -}
    format :: (Element t) => String -> (t -> String) -> Matrix t -> String
    format :: forall t.
    Element t =>
    FilePath -> (t -> FilePath) -> Matrix t -> FilePath
    format FilePath
    sep t -> FilePath
    f Matrix t
    m = FilePath -> [[FilePath]] -> FilePath
    table FilePath
    sep ([[FilePath]] -> FilePath)
    -> (Matrix t -> [[FilePath]]) -> Matrix t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([t] -> [FilePath]) -> [[t]] -> [[FilePath]]
    forall a b. (a -> b) -> [a] -> [b]
    map ((t -> FilePath) -> [t] -> [FilePath]
    forall a b. (a -> b) -> [a] -> [b]
    map t -> FilePath
    f) ([[t]] -> [[FilePath]])
    -> (Matrix t -> [[t]]) -> Matrix t -> [[FilePath]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Matrix t -> [[t]]
    forall t. Element t => Matrix t -> [[t]]
    toLists (Matrix t -> FilePath) -> Matrix t -> FilePath
    forall a b. (a -> b) -> a -> b
    $ Matrix t
    m

    {- | Show a matrix with \"autoscaling\" and a given number of decimal places.

    >>> putStr . disps 2 $ 120 * (3><4) [1..]
    3x4  E3
     0.12  0.24  0.36  0.48
     0.60  0.72  0.84  0.96
     1.08  1.20  1.32  1.44

    -}
    disps :: Int -> Matrix Double -> String
    disps :: Int -> Matrix Double -> FilePath
    disps Int
    d Matrix Double
    x = Matrix Double -> FilePath
    forall t. Matrix t -> FilePath
    sdims Matrix Double
    x FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    "  " FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ Int -> Matrix Double -> FilePath
    forall b t.
    (PrintfArg b, RealFrac b, Floating b, Num t, Element b, Show t) =>
    t -> Matrix b -> FilePath
    formatScaled Int
    d Matrix Double
    x

    {- | Show a matrix with a given number of decimal places.

    >>> dispf 2 (1/3 + ident 3)
    "3x3\n1.33  0.33  0.33\n0.33  1.33  0.33\n0.33  0.33  1.33\n"

    >>> putStr . dispf 2 $ (3><4)[1,1.5..]
    3x4
    1.00  1.50  2.00  2.50
    3.00  3.50  4.00  4.50
    5.00  5.50  6.00  6.50

    >>> putStr . unlines . tail . lines . dispf 2 . asRow $ linspace 10 (0,1)
    0.00  0.11  0.22  0.33  0.44  0.56  0.67  0.78  0.89  1.00

    -}
    dispf :: Int -> Matrix Double -> String
    dispf :: Int -> Matrix Double -> FilePath
    dispf Int
    d Matrix Double
    x = Matrix Double -> FilePath
    forall t. Matrix t -> FilePath
    sdims Matrix Double
    x FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    "\n" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ Int -> Matrix Double -> FilePath
    forall a t.
    (Show a, PrintfArg t, Element t) =>
    a -> Matrix t -> FilePath
    formatFixed (if Matrix Double -> Bool
    isInt Matrix Double
    x then Int
    0 else Int
    d) Matrix Double
    x

    sdims :: Matrix t -> [Char]
    sdims :: forall t. Matrix t -> FilePath
    sdims Matrix t
    x = Int -> FilePath
    forall a. Show a => a -> FilePath
    show (Matrix t -> Int
    forall t. Matrix t -> Int
    rows Matrix t
    x) FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    "x" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ Int -> FilePath
    forall a. Show a => a -> FilePath
    show (Matrix t -> Int
    forall t. Matrix t -> Int
    cols Matrix t
    x)

    formatFixed :: (Show a, Text.Printf.PrintfArg t, Element t)
                => a -> Matrix t -> String
    formatFixed :: forall a t.
    (Show a, PrintfArg t, Element t) =>
    a -> Matrix t -> FilePath
    formatFixed a
    d Matrix t
    x = FilePath -> (t -> FilePath) -> Matrix t -> FilePath
    forall t.
    Element t =>
    FilePath -> (t -> FilePath) -> Matrix t -> FilePath
    format FilePath
    "  " (FilePath -> t -> FilePath
    forall r. PrintfType r => FilePath -> r
    printf (FilePath
    "%."FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++a -> FilePath
    forall a. Show a => a -> FilePath
    show a
    dFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "f")) (Matrix t -> FilePath) -> Matrix t -> FilePath
    forall a b. (a -> b) -> a -> b
    $ Matrix t
    x

    isInt :: Matrix Double -> Bool
    isInt :: Matrix Double -> Bool
    isInt = (Double -> Bool) -> [Double] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Double -> Bool
    forall a. (Show a, RealFrac a) => a -> Bool
    lookslikeInt ([Double] -> Bool)
    -> (Matrix Double -> [Double]) -> Matrix Double -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector Double -> [Double]
    forall a. Storable a => Vector a -> [a]
    toList (Vector Double -> [Double])
    -> (Matrix Double -> Vector Double) -> Matrix Double -> [Double]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Matrix Double -> Vector Double
    forall t. Element t => Matrix t -> Vector t
    flatten

    formatScaled :: (Text.Printf.PrintfArg b, RealFrac b, Floating b, Num t, Element b, Show t)
                 => t -> Matrix b -> [Char]
    formatScaled :: forall b t.
    (PrintfArg b, RealFrac b, Floating b, Num t, Element b, Show t) =>
    t -> Matrix b -> FilePath
    formatScaled t
    dec Matrix b
    t = FilePath
    "E"FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++Int -> FilePath
    forall a. Show a => a -> FilePath
    show Int
    oFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "\n" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    ss
        where ss :: FilePath
    ss = FilePath -> (b -> FilePath) -> Matrix b -> FilePath
    forall t.
    Element t =>
    FilePath -> (t -> FilePath) -> Matrix t -> FilePath
    format FilePath
    " " (FilePath -> b -> FilePath
    forall r. PrintfType r => FilePath -> r
    printf FilePath
    fmt(b -> FilePath) -> (b -> b) -> b -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . b -> b
    forall {a}. Fractional a => a -> a
    g) Matrix b
    t
              g :: a -> a
    g a
    x | Int
    o Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    0    = a
    xa -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    10a -> Int -> a
    forall a b. (Num a, Integral b) => a -> b -> a
    ^(Int
    o::Int)
                  | Bool
    otherwise = a
    xa -> a -> a
    forall a. Num a => a -> a -> a
    *a
    10a -> Int -> a
    forall a b. (Num a, Integral b) => a -> b -> a
    ^(-Int
    o)
              o :: Int
    o | Matrix b -> Int
    forall t. Matrix t -> Int
    rows Matrix b
    t Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0 Bool -> Bool -> Bool
    || Matrix b -> Int
    forall t. Matrix t -> Int
    cols Matrix b
    t Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0 = Int
    0
                | Bool
    otherwise = b -> Int
    forall b. Integral b => b -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (b -> Int) -> b -> Int
    forall a b. (a -> b) -> a -> b
    $ [b] -> b
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum ([b] -> b) -> [b] -> b
    forall a b. (a -> b) -> a -> b
    $ (b -> b) -> [b] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    map (b -> b -> b
    forall a. Floating a => a -> a -> a
    logBase b
    10 (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . b -> b
    forall a. Num a => a -> a
    abs) ([b] -> [b]) -> [b] -> [b]
    forall a b. (a -> b) -> a -> b
    $ Vector b -> [b]
    forall a. Storable a => Vector a -> [a]
    toList (Vector b -> [b]) -> Vector b -> [b]
    forall a b. (a -> b) -> a -> b
    $ Matrix b -> Vector b
    forall t. Element t => Matrix t -> Vector t
    flatten Matrix b
    t
              fmt :: FilePath
    fmt = Char
    '%'Char -> FilePath -> FilePath
    forall a. a -> [a] -> [a]
    :t -> FilePath
    forall a. Show a => a -> FilePath
    show (t
    dect -> t -> t
    forall a. Num a => a -> a -> a
    +t
    3) FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ Char
    '.'Char -> FilePath -> FilePath
    forall a. a -> [a] -> [a]
    :t -> FilePath
    forall a. Show a => a -> FilePath
    show t
    dec FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "f"

    {- | Show a vector using a function for showing matrices.

    >>> putStr . vecdisp (dispf 2) $ linspace 10 (0,1)
    10 |> 0.00  0.11  0.22  0.33  0.44  0.56  0.67  0.78  0.89  1.00

    -}
    vecdisp :: (Element t) => (Matrix t -> String) -> Vector t -> String
    vecdisp :: forall t.
    Element t =>
    (Matrix t -> FilePath) -> Vector t -> FilePath
    vecdisp Matrix t -> FilePath
    f Vector t
    v
        = ((Int -> FilePath
    forall a. Show a => a -> FilePath
    show (Vector t -> Int
    forall t. Storable t => Vector t -> Int
    dim Vector t
    v) FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    " |> ") FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++) (FilePath -> FilePath)
    -> (Vector t -> FilePath) -> Vector t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "\n")
        (FilePath -> FilePath)
    -> (Vector t -> FilePath) -> Vector t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [FilePath] -> FilePath
    unwords ([FilePath] -> FilePath)
    -> (Vector t -> [FilePath]) -> Vector t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath]
    lines (FilePath -> [FilePath])
    -> (Vector t -> FilePath) -> Vector t -> [FilePath]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .  FilePath -> FilePath
    forall a. HasCallStack => [a] -> [a]
    tail (FilePath -> FilePath)
    -> (Vector t -> FilePath) -> Vector t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool) -> FilePath -> FilePath
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> FilePath -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` FilePath
    " \n"))
        (FilePath -> FilePath)
    -> (Vector t -> FilePath) -> Vector t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Matrix t -> FilePath
    f (Matrix t -> FilePath)
    -> (Vector t -> Matrix t) -> Vector t -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Matrix t -> Matrix t
    forall t. Matrix t -> Matrix t
    trans (Matrix t -> Matrix t)
    -> (Vector t -> Matrix t) -> Vector t -> Matrix t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Vector t -> Matrix t
    forall t. Storable t => Int -> Vector t -> Matrix t
    reshape Int
    1
        (Vector t -> FilePath) -> Vector t -> FilePath
    forall a b. (a -> b) -> a -> b
    $ Vector t
    v

    {- | Tool to display matrices with latex syntax.

    >>>  latexFormat "bmatrix" (dispf 2 $ ident 2)
    "\\begin{bmatrix}\n1  &  0\n\\\\\n0  &  1\n\\end{bmatrix}"

    -}
    latexFormat :: String -- ^ type of braces: \"matrix\", \"bmatrix\", \"pmatrix\", etc.
                -> String -- ^ Formatted matrix, with elements separated by spaces and newlines
                -> String
    latexFormat :: FilePath -> FilePath -> FilePath
    latexFormat FilePath
    del FilePath
    tab = FilePath
    "\\begin{"FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    delFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "}\n" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath -> FilePath
    f FilePath
    tab FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    "\\end{"FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    delFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "}"
        where f :: FilePath -> FilePath
    f = [FilePath] -> FilePath
    unlines ([FilePath] -> FilePath)
    -> (FilePath -> [FilePath]) -> FilePath -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath] -> [FilePath]
    forall a. a -> [a] -> [a]
    intersperse FilePath
    "\\\\" ([FilePath] -> [FilePath])
    -> (FilePath -> [FilePath]) -> FilePath -> [FilePath]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([FilePath] -> FilePath) -> [[FilePath]] -> [FilePath]
    forall a b. (a -> b) -> [a] -> [b]
    map [FilePath] -> FilePath
    unwords ([[FilePath]] -> [FilePath])
    -> (FilePath -> [[FilePath]]) -> FilePath -> [FilePath]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
    forall a b. (a -> b) -> [a] -> [b]
    map (FilePath -> [FilePath] -> [FilePath]
    forall a. a -> [a] -> [a]
    intersperse FilePath
    " & " ([FilePath] -> [FilePath])
    -> (FilePath -> [FilePath]) -> FilePath -> [FilePath]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath]
    words) ([FilePath] -> [[FilePath]])
    -> (FilePath -> [FilePath]) -> FilePath -> [[FilePath]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [FilePath] -> [FilePath]
    forall a. HasCallStack => [a] -> [a]
    tail ([FilePath] -> [FilePath])
    -> (FilePath -> [FilePath]) -> FilePath -> [FilePath]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath]
    lines

    -- | Pretty print a complex number with at most n decimal digits.
    showComplex :: Int -> Complex Double -> String
    showComplex :: Int -> Complex Double -> FilePath
    showComplex Int
    d (Double
    a:+Double
    b)
        | Double -> Bool
    forall a. Show a => a -> Bool
    isZero Double
    a Bool -> Bool -> Bool
    && Double -> Bool
    forall a. Show a => a -> Bool
    isZero Double
    b = FilePath
    "0"
        | Double -> Bool
    forall a. Show a => a -> Bool
    isZero Double
    b = FilePath
    sa
        | Double -> Bool
    forall a. Show a => a -> Bool
    isZero Double
    a Bool -> Bool -> Bool
    && Double -> Bool
    forall a. Show a => a -> Bool
    isOne Double
    b = FilePath
    s2FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "i"
        | Double -> Bool
    forall a. Show a => a -> Bool
    isZero Double
    a = FilePath
    sbFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "i"
        | Double -> Bool
    forall a. Show a => a -> Bool
    isOne Double
    b = FilePath
    saFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    s3FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "i"
        | Bool
    otherwise = FilePath
    saFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    s1FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    sbFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "i"
      where
        sa :: FilePath
    sa = Int -> Double -> FilePath
    forall a t1 t.
    (Show a, Show t1, PrintfType t, PrintfArg t1, RealFrac t1) =>
    a -> t1 -> t
    shcr Int
    d Double
    a
        sb :: FilePath
    sb = Int -> Double -> FilePath
    forall a t1 t.
    (Show a, Show t1, PrintfType t, PrintfArg t1, RealFrac t1) =>
    a -> t1 -> t
    shcr Int
    d Double
    b
        s1 :: FilePath
    s1 = if Double
    bDouble -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    <Double
    0 then FilePath
    "" else FilePath
    "+"
        s2 :: FilePath
    s2 = if Double
    bDouble -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    <Double
    0 then FilePath
    "-" else FilePath
    ""
        s3 :: FilePath
    s3 = if Double
    bDouble -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    <Double
    0 then FilePath
    "-" else FilePath
    "+"

    shcr :: (Show a, Show t1, Text.Printf.PrintfType t, Text.Printf.PrintfArg t1, RealFrac t1)
         => a -> t1 -> t
    shcr :: forall a t1 t.
    (Show a, Show t1, PrintfType t, PrintfArg t1, RealFrac t1) =>
    a -> t1 -> t
    shcr a
    d t1
    a | t1 -> Bool
    forall a. (Show a, RealFrac a) => a -> Bool
    lookslikeInt t1
    a = FilePath -> t1 -> t
    forall r. PrintfType r => FilePath -> r
    printf FilePath
    "%.0f" t1
    a
             | Bool
    otherwise      = FilePath -> t1 -> t
    forall r. PrintfType r => FilePath -> r
    printf (FilePath
    "%."FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++a -> FilePath
    forall a. Show a => a -> FilePath
    show a
    dFilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    "f") t1
    a

    lookslikeInt :: (Show a, RealFrac a) => a -> Bool
    lookslikeInt :: forall a. (Show a, RealFrac a) => a -> Bool
    lookslikeInt a
    x = Int -> FilePath
    forall a. Show a => a -> FilePath
    show (a -> Int
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round a
    x :: Int) FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++FilePath
    ".0" FilePath -> FilePath -> Bool
    forall a. Eq a => a -> a -> Bool
    == FilePath
    shx Bool -> Bool -> Bool
    || FilePath
    "-0.0" FilePath -> FilePath -> Bool
    forall a. Eq a => a -> a -> Bool
    == FilePath
    shx
       where shx :: FilePath
    shx = a -> FilePath
    forall a. Show a => a -> FilePath
    show a
    x

    isZero :: Show a => a -> Bool
    isZero :: forall a. Show a => a -> Bool
    isZero a
    x = a -> FilePath
    forall a. Show a => a -> FilePath
    show a
    x FilePath -> [FilePath] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [FilePath
    "0.0",FilePath
    "-0.0"]
    isOne :: Show a => a -> Bool
    isOne :: forall a. Show a => a -> Bool
    isOne  a
    x = a -> FilePath
    forall a. Show a => a -> FilePath
    show a
    x FilePath -> [FilePath] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [FilePath
    "1.0",FilePath
    "-1.0"]

    -- | Pretty print a complex matrix with at most n decimal digits.
    dispcf :: Int -> Matrix (Complex Double) -> String
    dispcf :: Int -> Matrix (Complex Double) -> FilePath
    dispcf Int
    d Matrix (Complex Double)
    m = Matrix (Complex Double) -> FilePath
    forall t. Matrix t -> FilePath
    sdims Matrix (Complex Double)
    m FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    "\n" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    -> (Complex Double -> FilePath)
    -> Matrix (Complex Double)
    -> FilePath
    forall t.
    Element t =>
    FilePath -> (t -> FilePath) -> Matrix t -> FilePath
    format FilePath
    "  " (Int -> Complex Double -> FilePath
    showComplex Int
    d) Matrix (Complex Double)
    m

    --------------------------------------------------------------------

    apparentCols :: FilePath -> IO Int
    apparentCols :: FilePath -> IO Int
    apparentCols FilePath
    s = [[FilePath]] -> Int
    forall {t :: * -> *} {a}. Foldable t => [t a] -> Int
    f ([[FilePath]] -> Int)
    -> (FilePath -> [[FilePath]]) -> FilePath -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([FilePath] -> Bool) -> [[FilePath]] -> [[FilePath]]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile [FilePath] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([[FilePath]] -> [[FilePath]])
    -> (FilePath -> [[FilePath]]) -> FilePath -> [[FilePath]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
    forall a b. (a -> b) -> [a] -> [b]
    map FilePath -> [FilePath]
    words ([FilePath] -> [[FilePath]])
    -> (FilePath -> [FilePath]) -> FilePath -> [[FilePath]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath]
    lines (FilePath -> Int) -> IO FilePath -> IO Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> FilePath -> IO FilePath
    readFile FilePath
    s
      where
        f :: [t a] -> Int
    f [] = Int
    0
        f (t a
    x:[t a]
    _) = t a -> Int
    forall a. t a -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length t a
    x

    -- | load a matrix from an ASCII file formatted as a 2D table.
    loadMatrix :: FilePath -> IO (Matrix Double)
    loadMatrix :: FilePath -> IO (Matrix Double)
    loadMatrix FilePath
    f = do
        v <- FilePath -> IO (Vector Double)
    vectorScan FilePath
    f
        c <- apparentCols f
        if (dim v `mod` c /= 0)
          then
            error $ printf "loadMatrix: %d elements and %d columns in file %s"
                           (dim v) c f
          else
            return (reshape c v)

    loadMatrix' :: FilePath -> IO (Maybe (Matrix Double))
    loadMatrix' :: FilePath -> IO (Maybe (Matrix Double))
    loadMatrix' FilePath
    name = IO (Matrix Double) -> IO (Maybe (Matrix Double))
    forall x. IO x -> IO (Maybe x)
    mbCatch (FilePath -> IO (Matrix Double)
    loadMatrix FilePath
    name)