    {-# OPTIONS_GHC -fno-warn-missing-signatures #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Plot
    -- Copyright   :  (c) Alberto Ruiz 2005-8
    -- License     :  GPL-style
    --
    -- Maintainer  :  Alberto Ruiz (aruiz at um dot es)
    -- Stability   :  provisional
    -- Portability :  uses gnuplot and ImageMagick
    --
    -- This module is deprecated. It can be replaced by improved drawing tools
    -- available in the plot\\plot-gtk packages by Vivian McPhail or Gnuplot by Henning Thielemann.
    -----------------------------------------------------------------------------
    {-# OPTIONS_HADDOCK hide #-}

    module Graphics.Plot(

        mplot,

        plot, parametricPlot,

        splot, mesh, meshdom,

        matrixToPGM, imshow,

        gnuplotX, gnuplotpdf, gnuplotWin

    ) where

    import Numeric.LinearAlgebra.HMatrix
    import Data.List(intersperse)
    import System.Process (system)

    -- | From vectors x and y, it generates a pair of matrices to be used as x and y arguments for matrix functions.
    meshdom :: Vector Double -> Vector Double -> (Matrix Double , Matrix Double)
    meshdom :: Vector Double -> Vector Double -> (Matrix Double, Matrix Double)
    meshdom Vector Double
    r1 Vector Double
    r2 = (Vector Double -> Vector Double -> Matrix Double
    forall t. Product t => Vector t -> Vector t -> Matrix t
    outer Vector Double
    r1 (Double -> Int -> Vector Double
    forall e d (c :: * -> *). Konst e d c => e -> d -> c e
    konst Double
    1 (Vector Double -> IndexOf Vector
    forall (c :: * -> *) t. Container c t => c t -> IndexOf c
    size Vector Double
    r2)), Vector Double -> Vector Double -> Matrix Double
    forall t. Product t => Vector t -> Vector t -> Matrix t
    outer (Double -> Int -> Vector Double
    forall e d (c :: * -> *). Konst e d c => e -> d -> c e
    konst Double
    1 (Vector Double -> IndexOf Vector
    forall (c :: * -> *) t. Container c t => c t -> IndexOf c
    size Vector Double
    r1)) Vector Double
    r2)

    {- | Draws a 3D surface representation of a real matrix.

    > > mesh $ build (10,10) (\\i j -> i + (j-5)^2)

    In certain versions you can interactively rotate the graphic using the mouse.

    -}
    mesh :: Matrix Double -> IO ()
    mesh :: Matrix Double -> IO ()
    mesh Matrix Double
    m = String -> IO ()
    gnuplotX (String
    commandString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    dat) where
        command :: String
    command = String
    "splot "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    datafollowsString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " matrix with lines\n"
        dat :: String
    dat = [[Double]] -> String
    prep ([[Double]] -> String) -> [[Double]] -> String
    forall a b. (a -> b) -> a -> b
    $ Matrix Double -> [[Double]]
    forall t. Element t => Matrix t -> [[t]]
    toLists Matrix Double
    m

    {- | Draws the surface represented by the function f in the desired ranges and number of points, internally using 'mesh'.

    > > let f x y = cos (x + y)
    > > splot f (0,pi) (0,2*pi) 50

    -}
    splot :: (Matrix Double->Matrix Double->Matrix Double) -> (Double,Double) -> (Double,Double) -> Int -> IO ()
    splot :: (Matrix Double -> Matrix Double -> Matrix Double)
    -> (Double, Double) -> (Double, Double) -> Int -> IO ()
    splot Matrix Double -> Matrix Double -> Matrix Double
    f (Double, Double)
    rx (Double, Double)
    ry Int
    n = Matrix Double -> IO ()
    mesh Matrix Double
    z where
        (Matrix Double
    x,Matrix Double
    y) = Vector Double -> Vector Double -> (Matrix Double, Matrix Double)
    meshdom (Int -> (Double, Double) -> Vector Double
    forall e.
    (Fractional e, Container Vector e) =>
    Int -> (e, e) -> Vector e
    linspace Int
    n (Double, Double)
    rx) (Int -> (Double, Double) -> Vector Double
    forall e.
    (Fractional e, Container Vector e) =>
    Int -> (e, e) -> Vector e
    linspace Int
    n (Double, Double)
    ry)
        z :: Matrix Double
    z = Matrix Double -> Matrix Double -> Matrix Double
    f Matrix Double
    x Matrix Double
    y

    {- | plots several vectors against the first one

    > > let t = linspace 100 (-3,3) in mplot [t, sin t, exp (-t^2)]

    -}
    mplot :: [Vector Double] -> IO ()
    mplot :: [Vector Double] -> IO ()
    mplot [Vector Double]
    m = String -> IO ()
    gnuplotX (String
    commandsString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    dats) where
        commands :: String
    commands = if [Vector Double] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Vector Double]
    m Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    1 then String
    command1 else String
    commandmore
        command1 :: String
    command1 = String
    "plot "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    datafollowsString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " with lines\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    dat
        commandmore :: String
    commandmore = String
    "plot " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    plots String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\n"
        plots :: String
    plots = [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    intersperse String
    ", " ((Int -> String) -> [Int] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> String
    forall {a}. Show a => a -> String
    cmd [Int
    2 .. [Vector Double] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Vector Double]
    m])
        cmd :: a -> String
    cmd a
    k = String
    datafollowsString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " using 1:"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++a -> String
    forall {a}. Show a => a -> String
    show a
    kString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " with lines"
        dat :: String
    dat = [[Double]] -> String
    prep ([[Double]] -> String) -> [[Double]] -> String
    forall a b. (a -> b) -> a -> b
    $ Matrix Double -> [[Double]]
    forall t. Element t => Matrix t -> [[t]]
    toLists (Matrix Double -> [[Double]]) -> Matrix Double -> [[Double]]
    forall a b. (a -> b) -> a -> b
    $ [Vector Double] -> Matrix Double
    forall t. Element t => [Vector t] -> Matrix t
    fromColumns [Vector Double]
    m
        dats :: String
    dats = [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat (Int -> String -> [String]
    forall a. Int -> a -> [a]
    replicate ([Vector Double] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Vector Double]
    mInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) String
    dat)

    {- | Draws a list of functions over a desired range and with a desired number of points

    > > plot [sin, cos, sin.(3*)] (0,2*pi) 1000

    -}
    plot :: [Vector Double->Vector Double] -> (Double,Double) -> Int -> IO ()
    plot :: [Vector Double -> Vector Double]
    -> (Double, Double) -> Int -> IO ()
    plot [Vector Double -> Vector Double]
    fs (Double, Double)
    rx Int
    n = [Vector Double] -> IO ()
    mplot (Vector Double
    xVector Double -> [Vector Double] -> [Vector Double]
    forall a. a -> [a] -> [a]
    : [Vector Double -> Vector Double]
    -> Vector Double -> [Vector Double]
    forall {p} {b}. [p -> b] -> p -> [b]
    mapf [Vector Double -> Vector Double]
    fs Vector Double
    x)
        where x :: Vector Double
    x = Int -> (Double, Double) -> Vector Double
    forall e.
    (Fractional e, Container Vector e) =>
    Int -> (e, e) -> Vector e
    linspace Int
    n (Double, Double)
    rx
              mapf :: [p -> b] -> p -> [b]
    mapf [p -> b]
    gs p
    y = ((p -> b) -> b) -> [p -> b] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    map ((p -> b) -> p -> b
    forall a b. (a -> b) -> a -> b
    $ p
    y) [p -> b]
    gs

    {- | Draws a parametric curve. For instance, to draw a spiral we can do something like:

    > > parametricPlot (\t->(t * sin t, t * cos t)) (0,10*pi) 1000

    -}
    parametricPlot :: (Vector Double->(Vector Double,Vector Double)) -> (Double, Double) -> Int -> IO ()
    parametricPlot :: (Vector Double -> (Vector Double, Vector Double))
    -> (Double, Double) -> Int -> IO ()
    parametricPlot Vector Double -> (Vector Double, Vector Double)
    f (Double, Double)
    rt Int
    n = [Vector Double] -> IO ()
    mplot [Vector Double
    fx, Vector Double
    fy]
        where t :: Vector Double
    t = Int -> (Double, Double) -> Vector Double
    forall e.
    (Fractional e, Container Vector e) =>
    Int -> (e, e) -> Vector e
    linspace Int
    n (Double, Double)
    rt
              (Vector Double
    fx,Vector Double
    fy) = Vector Double -> (Vector Double, Vector Double)
    f Vector Double
    t

    -- | writes a matrix to pgm image file
    matrixToPGM :: Matrix Double -> String
    matrixToPGM :: Matrix Double -> String
    matrixToPGM Matrix Double
    m = String
    header String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ [String] -> String
    unlines (([String] -> String) -> [[String]] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map [String] -> String
    unwords [[String]]
    ll) where
        c :: Int
    c = Matrix Double -> Int
    forall t. Matrix t -> Int
    cols Matrix Double
    m
        r :: Int
    r = Matrix Double -> Int
    forall t. Matrix t -> Int
    rows Matrix Double
    m
        header :: String
    header = String
    "P2 "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++Int -> String
    forall {a}. Show a => a -> String
    show Int
    cString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++Int -> String
    forall {a}. Show a => a -> String
    show Int
    rString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++Int -> String
    forall {a}. Show a => a -> String
    show (Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round Double
    maxgray :: Int)String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "\n"
        maxgray :: Double
    maxgray = Double
    255.0
        maxval :: Double
    maxval = Matrix Double -> Double
    forall (c :: * -> *) e. Container c e => c e -> e
    maxElement Matrix Double
    m
        minval :: Double
    minval = Matrix Double -> Double
    forall (c :: * -> *) e. Container c e => c e -> e
    minElement Matrix Double
    m
        scale' :: Double
    scale' = if Double
    maxval Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    minval
            then Double
    0.0
            else Double
    maxgray Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / (Double
    maxval Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    minval)
        f :: Double -> String
    f Double
    x = Int -> String
    forall {a}. Show a => a -> String
    show ( Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round ( Double
    scale' Double -> Double -> Double
    forall a. Num a => a -> a -> a
    *(Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    minval) ) :: Int )
        ll :: [[String]]
    ll = ([Double] -> [String]) -> [[Double]] -> [[String]]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Double -> String) -> [Double] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map Double -> String
    f) (Matrix Double -> [[Double]]
    forall t. Element t => Matrix t -> [[t]]
    toLists Matrix Double
    m)

    -- | imshow shows a representation of a matrix as a gray level image using ImageMagick's display.
    imshow :: Matrix Double -> IO ()
    imshow :: Matrix Double -> IO ()
    imshow Matrix Double
    m = do
        _ <- String -> IO ExitCode
    system (String -> IO ExitCode) -> String -> IO ExitCode
    forall a b. (a -> b) -> a -> b
    $ String
    "echo \""String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Matrix Double -> String
    matrixToPGM Matrix Double
    m String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "\"| display -antialias -resize 300 - &"
        return ()

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

    gnuplotX :: String -> IO ()
    gnuplotX :: String -> IO ()
    gnuplotX String
    command = do { _ <- String -> IO ExitCode
    system String
    cmdstr; return()} where
        cmdstr :: String
    cmdstr = String
    "echo \""String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    commandString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "\" | gnuplot -persist"

    datafollows :: String
    datafollows = String
    "\\\"-\\\""

    prep :: [[Double]] -> String
    prep = (String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "e\n\n") (String -> String)
    -> ([[Double]] -> String) -> [[Double]] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> String
    unlines ([String] -> String)
    -> ([[Double]] -> [String]) -> [[Double]] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Double] -> String) -> [[Double]] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map ([String] -> String
    unwords ([String] -> String)
    -> ([Double] -> [String]) -> [Double] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Double -> String) -> [Double] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map Double -> String
    forall {a}. Show a => a -> String
    show)

    gnuplotpdf :: String -> String -> [([[Double]], String)] -> IO ()
    gnuplotpdf :: String -> String -> [([[Double]], String)] -> IO ()
    gnuplotpdf String
    title String
    command [([[Double]], String)]
    ds = String -> IO ()
    gnuplot (String
    prelude String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    command String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    draw) IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> IO ()
    postproc where
        prelude :: String
    prelude = String
    "set terminal epslatex color; set output '"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    titleString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    ".tex';"
        ([[[Double]]]
    dats,[String]
    defs) = [([[Double]], String)] -> ([[[Double]]], [String])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [([[Double]], String)]
    ds
        draw :: String
    draw = [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat (String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    intersperse String
    ", " ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String
    "\"-\" "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++) [String]
    defs)) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
               ([[Double]] -> String) -> [[[Double]]] -> String
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap [[Double]] -> String
    pr [[[Double]]]
    dats
        postproc :: IO ()
    postproc = do
            _ <- String -> IO ExitCode
    system (String -> IO ExitCode) -> String -> IO ExitCode
    forall a b. (a -> b) -> a -> b
    $ String
    "epstopdf "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    titleString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    ".eps"
            mklatex
            _ <- system $ "pdflatex "++title++"aux.tex > /dev/null"
            _ <- system $ "pdfcrop "++title++"aux.pdf > /dev/null"
            _ <- system $ "mv "++title++"aux-crop.pdf "++title++".pdf"
            _ <- system $ "rm "++title++"aux.* "++title++".eps "++title++".tex"
            return ()

        mklatex :: IO ()
    mklatex = String -> String -> IO ()
    writeFile (String
    titleString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "aux.tex") (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $
           String
    "\\documentclass{article}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "\\usepackage{graphics}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "\\usepackage{nopageno}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "\\usepackage{txfonts}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "\\renewcommand{\\familydefault}{phv}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "\\usepackage[usenames]{color}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++

           String
    "\\begin{document}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++

           String
    "\\begin{center}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "  \\input{./"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    titleString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    ".tex}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
           String
    "\\end{center}\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++

           String
    "\\end{document}"

        pr :: [[Double]] -> String
    pr = (String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "e\n") (String -> String)
    -> ([[Double]] -> String) -> [[Double]] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> String
    unlines ([String] -> String)
    -> ([[Double]] -> [String]) -> [[Double]] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Double] -> String) -> [[Double]] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map ([String] -> String
    unwords ([String] -> String)
    -> ([Double] -> [String]) -> [Double] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Double -> String) -> [Double] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map Double -> String
    forall {a}. Show a => a -> String
    show)

        gnuplot :: String -> IO ()
    gnuplot String
    cmd = do
            String -> String -> IO ()
    writeFile String
    "gnuplotcommand" String
    cmd
            _ <- String -> IO ExitCode
    system String
    "gnuplot gnuplotcommand"
            _ <- system "rm gnuplotcommand"
            return ()

    gnuplotWin :: String -> String -> [([[Double]], String)] -> IO ()
    gnuplotWin :: String -> String -> [([[Double]], String)] -> IO ()
    gnuplotWin String
    title String
    command [([[Double]], String)]
    ds = String -> IO ()
    gnuplot (String
    prelude String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    command String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    " "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    draw) where
        ([[[Double]]]
    dats,[String]
    defs) = [([[Double]], String)] -> ([[[Double]]], [String])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [([[Double]], String)]
    ds
        draw :: String
    draw = [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat (String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    intersperse String
    ", " ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String
    "\"-\" "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++) [String]
    defs)) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\n" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
               ([[Double]] -> String) -> [[[Double]]] -> String
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap [[Double]] -> String
    pr [[[Double]]]
    dats

        pr :: [[Double]] -> String
    pr = (String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "e\n") (String -> String)
    -> ([[Double]] -> String) -> [[Double]] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> String
    unlines ([String] -> String)
    -> ([[Double]] -> [String]) -> [[Double]] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Double] -> String) -> [[Double]] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map ([String] -> String
    unwords ([String] -> String)
    -> ([Double] -> [String]) -> [Double] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Double -> String) -> [Double] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map Double -> String
    forall {a}. Show a => a -> String
    show)

        prelude :: String
    prelude = String
    "set title \""String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    titleString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    "\";"

        gnuplot :: String -> IO ()
    gnuplot String
    cmd = do
            String -> String -> IO ()
    writeFile String
    "gnuplotcommand" String
    cmd
            _ <- String -> IO ExitCode
    system String
    "gnuplot -persist gnuplotcommand"
            _ <- system "rm gnuplotcommand"
            return ()