packages feed

loopy-0.0: Types.hs

{-# LANGUAGE ScopedTypeVariables #-}
module Types where


import System.Environment
import System.Random
import Control.Monad
import System.Directory
import System.Cmd
import Data.Char
import Data.Maybe
import Data.List
import Numeric
import System.FilePath
--maybe also contain basic utilities

type Matrix a = [[a]]

data Info = Info -- this says what is in the second input matrix
    {deathRate :: Double
    ,aeff :: Double
    ,peff :: Double
    ,biomass :: Double
    } deriving Show
    
data Foodweb = Foodweb
     {names :: [String]
     , info :: [Info]
     , wij :: Matrix Double
     ,cm :: Matrix Double
     } deriving Show
     
     

fileToFoodweb :: FilePath -> IO Foodweb
fileToFoodweb = readFoodweb -- FIXME: Inline this everywhere


readFoodweb :: FilePath -> IO Foodweb
readFoodweb file = do
	input <-readFile file
	let [names,info,wij] :: [Matrix String] = map toMatrix (splitString (lines (formatString input)))
	return $ Foodweb (matrixStringToListString names) (map toInfo (matrixStringToDouble info)) (matrixStringToDouble wij) undefined


returnComponents :: FilePath -> IO [String]
returnComponents fp = do
	input <-readFile fp
	output <- return $ splitString (lines (formatString input))
	return(output)
	
writeFoodweb :: FilePath -> Foodweb -> IO ()
writeFoodweb file (Foodweb names info wij _) = writeFile file $ unlines $
	names ++
	[""] ++
	map (intercalate "\t" . map show . infoToDouble) info ++
	[""] ++
	[outputMatrix (map2 show wij)]
	

formatString :: String -> String
formatString input =  unlines $ dropWhile null $ map (dropWhile isSpace) $ lines input
-- unlines takes list of strings to string
splitString :: [String] -> [String]
splitString input =	
	if null xs then
		 []
	else
		(unlines y:splitString ys )
	where xs = dropWhile null input
	      (y,ys) = break null xs
		
--readFile :: FilePath -> IO String
-- show stringyfys ints, doubles, lists of stuff, tuples , boolens, strings to strings
splitAndWriteFile :: FilePath -> IO ()
splitAndWriteFile file = do
	input <- readFile file
	output :: [Matrix String]<- return (map toMatrix (splitString (lines (formatString input))))
	createDirectoryIfMissing True ("input")
	names <- return [ ("input/" ++ dropExtension file ++ show i ++".txt")| i <- [1..] ]--return (dropExtension file ++ matrixNumber)
	sequence $ map (uncurry writeFile) (zip names (map show output))
	return ()
 --uncurry takes a 2 input function and makes it accept a tuple instead
    

--replace any non empty sequences of space with tab
tabify (x:xs) | isSpace x = '\t' : tabify (dropWhile isSpace xs)
              | otherwise = x : tabify xs
tabify [] = []

matrixFromList :: [[a]] -> Matrix a
matrixFromList x = x


toInfo :: [Double] -> Info
toInfo [_,a,b,c,d] = Info a b c d

show3dp :: Double -> String
show3dp x = showFFloat (Just 3) x ""

infoToMatrixDouble :: [Info] -> Matrix Double
infoToMatrixDouble input = map infoToDouble input

infoToDouble :: Info -> [Double]
infoToDouble (Info a b c d) = [0,a,b,c,d]

mean :: [Double] -> Double
mean a = sum(a)/(fromIntegral (length(a))) --  cant' divide a double by an int

functionToMatrix :: (Int -> Int -> Double) -> Int -> Matrix Double
functionToMatrix f len = [[f i j | j <- [0..(len-1)]]| i <-[0..(len-1)]]

outputMatrix :: Matrix String -> String
outputMatrix = unlines . map (concat . intersperse "\t")

toMatrix :: String -> Matrix String
toMatrix input = map words (lines  input) 

matrixStringToListString :: Matrix String -> [String]
matrixStringToListString = map head

matrixStringToDouble :: Matrix String -> Matrix Double
matrixStringToDouble input =  map (map read) input

matrixDoubleToString :: Matrix Double -> Matrix String
matrixDoubleToString input = map (map show) input

stringsToMatrixDouble :: [String] -> Matrix Double
stringsToMatrixDouble input = matrixStringToDouble $ map words input
	
--applys a function to a matrix element, then returns the changed function
mapInd :: (Int->a->b) -> [a] -> [b]
mapInd f a = zipWith f [1..] a

changeElemList :: Int -> (Double -> Double) -> [Double] -> [Double]
changeElemList i f a = mapInd (\inew x -> if inew ==i then f x else x) a

mapMatrixInd ::(Int->Int->a->b) ->  Matrix a -> Matrix b
mapMatrixInd f xs = mapInd (\i x -> mapInd (f i) x) xs

changeElem :: Int -> Int -> (Double -> Double) ->Matrix Double -> Matrix Double
changeElem i j f m =  mapMatrixInd (\inew jnew x -> if inew== i && jnew == j then f x else x ) m

--applys a function to a matrix element, then returns the changed function
mapInd0 :: (Int->a->b) -> [a] -> [b]
mapInd0 f a = zipWith f [0..] a

mapMatrixInd0 ::(Int->Int->a->b) ->  Matrix a -> Matrix b
mapMatrixInd0 f xs = mapInd0 (\i x -> mapInd0 (f i) x) xs



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

--matrix :: Size -> (Int -> Int -> a) -> Matrix a
--matrix _ m = m

-------------------------------
--vectorToList :: Size -> Vector a -> [a]
--vectorToList n v = [v i | i <- [0..n-1]]

--matrixToList :: Size -> Matrix a -> [[a]]
--matrixToList n m = [vectorToList n $ m i | i <- [0..n-1]]

--operation

transposeMatrix m i j = m j i  

rowMatrix m i = m i

colMatrix m j = \i -> m i j

-- General

map2 :: (a -> b) -> [[a]] -> [[b]]
map2 f = map (map f)


table :: String -> [[String]]
table = map words . lines