neural-0.3.0.1: examples/sin/Graph.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Graph where
import Control.Monad
import Control.Monad.ST (ST, runST)
import qualified Data.Array.Unboxed as U
import qualified Data.Array.ST as ST
graph :: (Double -> Double) -> Double -> Double -> Int -> Int -> IO ()
graph f xMin xMax height width = do
let a = array
forM_ [1..height] $ \y -> do
forM_ [1..width] $ \x -> putChar (a U.! (y, x))
putChar '\n'
where
array :: U.UArray (Int, Int) Char
array = runST $ do
a <- ST.newArray ((1, 1), (height, width)) ' ' :: forall s. ST s (ST.STUArray s (Int, Int) Char)
let dx = (xMax - xMin) / fromIntegral (pred width)
xys = [let x = xMin + fromIntegral j * dx in (x, f x) | j <- [0 .. pred width]]
ys = snd <$> xys
yMin = minimum ys
yMax = maximum ys
x_to_j x = round $ (x - xMin) / (xMax - xMin) * fromIntegral (pred width) + 1
j_to_x j = xMin + dx * fromIntegral (pred j)
y_to_i y = height - round ((y - yMin) / (yMax - yMin) * fromIntegral (pred height))
draw a x_to_j j_to_x y_to_i
ST.freeze a
where
draw :: forall s. ST.STUArray s (Int, Int) Char -> (Double -> Int) -> (Int -> Double) -> (Double -> Int) -> ST s ()
draw a x_to_j j_to_x y_to_i = drawXAxis >> drawYAxis >> drawGraph
where
drawXAxis :: ST s ()
drawXAxis = do
let i = y_to_i 0
when (i >= 1 && i <= height) $
forM_ [1..width] $ \j -> ST.writeArray a (i, j) '-'
drawYAxis :: ST s ()
drawYAxis = do
let j = x_to_j 0
when (j >= 1 && j <= width) $
forM_ [1..height] $ \i -> ST.writeArray a (i, j) '-'
drawGraph :: ST s ()
drawGraph = forM_ [1..width] $ \j -> do
let x = j_to_x j
y = f x
i = y_to_i y
ST.writeArray a (i, j) '*'