loopy-0.0: LoopProp.hs
--need to change matrix types
-- trace (show (a,b,c))
module LoopProp where
import Types
import Graph
import Data.Function
import Control.Arrow
import Data.List
import Data.Maybe
import Graphics.Google.Chart
import Data.Map(Map)
import qualified Data.Map as Map
import Debug.Trace
{-
Options:
divide by d or not
showing mlw loop, option to choose any of the other loops to show,
generate graph with r^2 value, or just output r^2 val
-}
-- A loop (propLoop) and properties about that loop
data Prop = Prop
{propLoop :: !Loop
,propLength :: !Int
,propWeight :: !Double
,propPositive :: !Bool
,propEven :: !Int
,propNet :: !Double
}
deriving Show
-- The properties on a set of loops
data PropSum = PropSum
{propsLength :: !Int
,propsTotal :: !Int
,propsAll :: !(Maybe Prop) -- need to check that it is just positive and negative, not All including net
,propsPositive :: !(Maybe Prop)
,propsNegative :: !(Maybe Prop)
,propsEven :: !(Maybe Prop)
,propsOmni:: !(Maybe Prop)
,propsNet:: !(Maybe Prop) -- the addition of the forward and back loops
}
deriving Show
----------------
propSum :: Prop -> PropSum
propSum p = PropSum (propLength p) 1
(test True) (test $ propPositive p) (test $ not $ propPositive p) (test $ propEven p == 0) -- changed first bracket from just (test True) $ propEven p /= propLength p
(test $ propEven p == 2 - propLength p || propEven p ==propLength p - 2) (test True)
where test b = if b then Just p else Nothing
propSumOutput :: Prop -> String
propSumOutput p = (show (propLoop p))++ "\t"++(show (propLength p)) ++ "\t"++ (show3dp (propWeight p) )++ "\t"++ (if (propPositive p) then "+" else "-" ) ++ "\t"++ (show (propEven p)) ++ "\t"++ (show3dp (propNet p)) ++ "\n"
--adds two propSums together, taking the maximum values
propSumPlus :: PropSum -> PropSum -> PropSum
propSumPlus a b = PropSum (propsLength a) (propsTotal a + propsTotal b)
(both propsAll) (both propsPositive) (both propsNegative) (both propsEven) (both propsOmni) (bothr propsNet)
where
both f = join (f a) (f b)
join Nothing x = x
join x Nothing = x
join (Just a) (Just b) | propWeight a > propWeight b = Just a
| otherwise = Just b
bothr f = joinr (f a) (f b)
joinr Nothing x = x
joinr x Nothing = x
joinr (Just a) (Just b) | propNet a > propNet b = Just a
| otherwise = Just b
--check that code written this week for signum is correct
-- | Finds the properties for a loop, m is the interaction matrix
classify :: Matrix Double -> Loop -> Prop
classify m loop = Prop loop n -- the loop and the length of the loop
(abs (pas / product ds) ** (1 / fromIntegral n)) -- weight of loop-- / product ds taken out dividing by diag for richard law things....
(pas > 0) -- is the loop positive
(sum $ map (round . signum) as) -- the sum of the loop
(abs ( (abs (pas / product ds) ** (1 / fromIntegral n)) - (abs (pasr / product ds) ** (1 / fromIntegral n)) ))-- reverse weight of loop--
where
pas = product as
as = map (\(x,y) -> m !! x !! y) $ links loop
ds = [m!!i!!i | i <- loop]
n = length loop
pasr = product asr
asr = map (\(x,y) -> m !! x !! y) $ links $ reverse loop
-- sorted by the Int
separate :: [Prop] -> [(Int, [Prop])]
separate = map (fst . head &&& map snd) . groupBy ((==) `on` fst) . sortBy (compare `on` fst) . map (propLength &&& id)
summarize :: [Prop] -> [PropSum]
summarize = Map.elems . foldl' f Map.empty
where
f :: Map Int PropSum -> Prop -> Map Int PropSum
f mp x = Map.insertWith' propSumPlus (propLength x) (propSum x) mp
propSumRow :: PropSum -> [String]
propSumRow (PropSum a b c d e f h i) = [show a, show b, g c, g d, g e, g f, g h, g3 i, g2 c]
where g = maybe "NA" (show3dp . propWeight)
g2 (Just x) = show $ propLoop x
g3 = maybe "NA" (show3dp . propNet)
---propSumRowOmni currently doesn't work 25th aug 10
propSumRowOmni :: PropSum -> [String]
propSumRowOmni (PropSum a b c d e f h i) = [show a, show b, g c, g d, g e, g f, g h, g3 i, g2 h]
where g = maybe "NA" (show3dp . propWeight)
g2 = maybe "NA" (show . propLoop)
g3 = maybe "NA" (show3dp . propNet)
propSumRowChoice :: Int -> PropSum -> [String]
propSumRowChoice i1 (PropSum a b c d e f h i) = [show a, show b, g c, g d, g e, g f, g h, g3 i, g2 l1]
where g = maybe "NA" (show3dp . propWeight)
g3 = maybe "NA" (show3dp . propNet)
g2 = maybe "NA" (show . propLoop)
l1 = if i1 == 1 then c else
if i1 == 2 then d else
if i1 == 3 then e else
if i1 == 4 then f else
if i1 == 5 then h else i
{--}
-- [1,2,3] = [(1,2),(2,3),(3,1)]
links :: [Int] -> [(Int,Int)]
links (x:xs) = f x xs
where f y [] = [(y,x)]
f y (z:zs) = (y,z) : f z zs
outputChart :: [PropSum] -> String
outputChart xs = chartURL $
setSize 400 257 $
setTitle "Maximum Loop Weights" $
setData (encodeDataSimple $ map f [propsAll,propsPositive,propsNegative,propsEven]) $
setDataColors ["000000","FF0000","0000FF","00000088"] $
setAxisLabels [map (show . propsLength) xs, ["0",show3dp mx]] $
setAxisTypes [AxisBottom, AxisLeft] $
setLegend ["MLW","MLW+","MLW-","MLWe"] $
newLineChart
where
mx = maximum $ map propWeight $ catMaybes $ concat [[a,b,c,d,e,f] | PropSum _ _ a b c d e f<- xs]
f g = [floor $ (i * 61) / mx | y <- map g xs, let i = maybe 0 propWeight y]
--type LoopPropFile = [PropSum]
--convert :: [String] -> PropSum
--convert [a,b,c,d,e,f]=PropSum (read a) (read b) (read c) (read d) (read e) (read f)
{-
-}