module LTA.Symbolic
( Expr(..)
+ , Cond(..)
, Constant(..)
, Literal(..)
+ , CompareOp(..)
, UnaryFunction(..)
+ , buildConditional
, pow
, simplify
+ , (~==)
+ , (~<)
+ , (~<=)
+ , (~>)
+ , (~>=)
) where
import Control.Applicative ((<$>))
import Data.Ratio (numerator, denominator)
import Data.List (foldl')
import Data.Map (Map)
+import Data.Set (Set)
import qualified Data.Map as Map
+import qualified Data.Set as Set
data SumTag
data ProductTag
| UnaryFunction UnaryFunction Expr
| Div Expr Expr
| Mod Expr Expr
+ | Conditional Cond Expr Expr
+ deriving (Eq, Ord, Show)
+
+data CompareOp
+ = Equal
+ | LessThan
+ | LessThanEqual
+ | GreaterThan
+ | GreaterThanEqual
+ deriving (Eq, Ord, Show)
+
+data Cond
+ = TrueC
+ | FalseC
+ | Compare CompareOp Expr Expr
+ | And Cond Cond
+ | Or Cond Cond
+ | Not Cond
deriving (Eq, Ord, Show)
data Literal
| Signum
deriving (Eq, Ord, Show)
+buildConditional :: Expr -> [(Cond, Expr)] -> Expr
+buildConditional base [] = base
+buildConditional base ((cond, expr) : cases) =
+ Conditional cond expr (buildConditional base cases)
+
+(~<) :: Expr -> Expr -> Cond
+(~<) = Compare LessThan
+
+(~<=) :: Expr -> Expr -> Cond
+(~<=) = Compare LessThanEqual
+
+(~==) :: Expr -> Expr -> Cond
+(~==) = Compare Equal
+
+(~>=) :: Expr -> Expr -> Cond
+(~>=) = Compare GreaterThanEqual
+
+(~>) :: Expr -> Expr -> Cond
+(~>) = Compare GreaterThan
+
simplify :: Expr -> Expr
simplify (Sum pairSeq) = rebuild $ normalise pairSeq
simplify (Product pairSeq) = rebuild $ normalise pairSeq
import LTA.Symbolic
main :: IO()
-main = putStrLn $ show dft
+main = putStrLn . show $ dft (IntegerSymbol "N")
row :: Expr
row = IntegerSymbol "row"
col :: Expr
col = IntegerSymbol "col"
-n :: Expr
-n = IntegerSymbol "N"
-
e :: Expr
e = Constant Euler
pi :: Expr
pi = Constant Pi
-dft :: Expr
-dft = pow e ((- i * 2 * Main.pi * row * col) / n)
+dft :: Expr -> Expr
+dft size = pow e ((- i * 2 * Main.pi * row * col) / size)
+
+isEven :: Expr -> Cond
+isEven n = (n `Mod` 2) ~== 0
+
+pad :: Expr -> Expr
+pad size = Conditional (isEven size) (evenPad size) (oddPad size)
+
+evenPad :: Expr -> Expr
+evenPad size = buildConditional 0 conditions where
+ split = size `Div` 2
+ conditions = [ ((row ~== col) `And` (row ~< split), 1)
+ , ((row ~== col) `And` (row ~== split), 0.5)
+ , ((row ~> split) `And` (row ~< (size + split)), 0)
+ , ((row ~== (size + split)) `And` (col ~== split), 0.5)
+ , ((row ~> (size + split)) `And` (row ~== (col + size + split)), 1)
+ ]
+
+oddPad :: Expr -> Expr
+oddPad size = buildConditional 0 conditions where
+ split = (size + 1) `Div` 2
+ conditions = [ ((row ~== col) `And` (row ~< split), 1)
+ , ((row ~>= split) `And` (row ~< (size + split)), 0)
+ , ((row ~>= (size + split)) `And` (row ~== (col + size + split)), 1)
+ ]