4 import TypesettingTricks
9 mapSignal:: (Physical a, Physical b) => (s a b) -> a -> b
10 mapSigList:: (Physical a, Physical b) => (s a b) -> [a] -> [b]
11 toSig:: (Physical a, Physical b) => (s a b) -> SignalRep a b
12 mapSignal = mapSignal . toSig
13 mapSigList = map . mapSignal
14 toSig = FunctionRep . mapSignal
15 instance Signal (->) where
18 data {- (Physical a, Physical b) => -} SignalRep a b =
19 FunctionRep (a -> b) |
20 PieceContRep (PieceCont a b)
22 instance Eq (SignalRep a b) where
23 (==) a b = error "No equality for SignalRep"
25 instance Show (SignalRep a b) where
26 show sr = error "No show for SignalRep"
28 instance Signal SignalRep where
29 mapSignal (FunctionRep f) = mapSignal f
30 mapSignal (PieceContRep f) = mapSignal f
31 mapSigList (FunctionRep f) = mapSigList f
32 mapSigList (PieceContRep f) = mapSigList f
34 instance (Physical a, Physical b) => Eq (a -> b) where
35 a == b = error "Attempt to apply equality to functions"
36 binop:: (Physical a, Physical b) => (Float -> Float -> Float) ->
37 (a -> b) -> (a -> b) -> a -> b
38 binop op f g t = toPhysical ((fromPhysical (f t)) `op` (fromPhysical (g t)))
39 unop:: (Physical a, Physical b ) => (Float -> Float) ->
41 unop op f t = toPhysical (op (fromPhysical (f t)))
42 instance (Physical a, Physical b) => Num (SignalRep a b) where
43 f + g = FunctionRep (binop (+) (mapSignal f) (mapSignal g))
44 f * g = FunctionRep (binop (*) (mapSignal f) (mapSignal g))
45 negate f = FunctionRep (unop negate (mapSignal f))
46 abs f = FunctionRep (unop abs (mapSignal f))
47 signum f = FunctionRep (unop abs (mapSignal f))
48 fromInteger i = FunctionRep (\t -> toPhysical (fromInteger i))
49 fromInt i = FunctionRep (\t -> toPhysical (fromInt i))
50 instance (Physical a, Physical b) =>
51 Fractional (SignalRep a b) where
52 f / g = FunctionRep (binop (/) (mapSignal f) (mapSignal g))
53 fromRational r = FunctionRep (\t -> (toPhysical (fromRational r)))
54 instance (Physical a, Physical b) =>
55 Floating (SignalRep a b) where
56 pi = FunctionRep (\t -> (toPhysical pi))
57 exp f = FunctionRep (unop exp (mapSignal f))
58 log f = FunctionRep (unop log (mapSignal f))
59 sin f = FunctionRep (unop sin (mapSignal f))
60 cos f = FunctionRep (unop cos (mapSignal f))
61 asin f = FunctionRep (unop asin (mapSignal f))
62 acos f = FunctionRep (unop acos (mapSignal f))
63 atan f = FunctionRep (unop atan (mapSignal f))
64 sinh f = FunctionRep (unop sinh (mapSignal f))
65 cosh f = FunctionRep (unop cosh (mapSignal f))
66 asinh f = FunctionRep (unop asinh (mapSignal f))
67 acosh f = FunctionRep (unop acosh (mapSignal f))
68 atanh f = FunctionRep (unop atanh (mapSignal f))
71 FunctionEvent (Float -> Bool) |
74 instance Show Event where
75 show (TimeEvent f) = "TimeEvent " ++ show f
76 show (FunctionEvent _) = "FunctionEvent"
77 show (BurstEvent i e) = "BurstEvent " ++ show i ++ " " ++ show e
79 instance Eq Event where
80 (TimeEvent x) == (TimeEvent y) = x == y
81 (BurstEvent i e) == (BurstEvent i' e') = (i' == i) && (e' == e)
82 eventOccurs:: Event -> Float -> Float
83 eventOccurs (TimeEvent t) x = if x < t then x else t
84 eventOccurs (FunctionEvent f) x = stepEval f x
85 eventOccurs (BurstEvent i e) x =
89 eventOccurs (BurstEvent (i-1) e) ((eventOccurs e x) + eventEps x)
90 stepEval:: (Float -> Bool) -> Float -> Float
91 stepEval f x = if f x then x else stepEval f (x + eventEps x)
92 data ZeroIndicator = LocalZero | GlobalZero deriving (Eq, Show)
93 data {- (Physical a, Physical b) => -} FunctionWindow a b =
94 Window ZeroIndicator Event (SignalRep a b)
96 data PieceCont a b = Windows [FunctionWindow a b]
98 instance Signal PieceCont where
99 mapSignal (Windows []) t = toPhysical 0.0
100 mapSignal (Windows wl) t = (mapSignal s) (toPhysical t')
101 where (t', (Window z e s), wl') = getWindow 0.0 (fromPhysical t) wl
103 getWindow:: (Physical a, Physical b) =>
104 Float -> Float -> [ FunctionWindow a b ] ->
105 (Float, FunctionWindow a b, [ FunctionWindow a b ])
106 getWindow st t [] = (t, Window LocalZero e f, [])
107 where e = TimeEvent (realmul 2 t)
108 f = FunctionRep (\t -> toPhysical 0.0)
109 getWindow st t (w:wl) = if t' <= wt then (t',w,w:wl)
110 else getWindow (st+wt) t wl
111 where wt = eventOccurs e t'
113 t' = if z == LocalZero then t-st else t
114 (|>) :: (Physical a, Physical b) => FunctionWindow a b ->
115 PieceCont a b -> PieceCont a b
116 w |> (Windows wl) = Windows (w:wl)
117 nullWindow = Windows []
118 cycleWindows:: (Physical a, Physical b) =>
119 PieceCont a b -> PieceCont a b
120 cycleWindows (Windows wl) = Windows (cycle wl)
121 constant:: (Physical a, Physical b) => b -> SignalRep a b
122 constant x = FunctionRep (\t -> x)
123 linear:: (Physical a, Physical b) => Float -> b -> SignalRep a b
124 linear m b = FunctionRep (\x -> toPhysical (realmul m (fromPhysical x) + (fromPhysical b)))
125 sine:: (Physical a, Physical b) =>
126 b -> Frequency -> Float -> SignalRep a b
127 sine mag omeg phase = FunctionRep (\x -> toPhysical (realmul (fromPhysical mag) (sin (realmul (realmul (realmul 2 pi) (fromPhysical omeg)) (fromPhysical x) + phase))))
128 waveform:: (Physical a, Physical b) => a -> [b] -> SignalRep a b
129 waveform samp ampls =
130 let stepSlope y y' = realdiv ((fromPhysical y') - (fromPhysical y)) (fromPhysical samp)
131 makeWin (v,v') = Window LocalZero (TimeEvent (fromPhysical samp))
132 (linear (stepSlope v v') v)
134 in PieceContRep (Windows (map makeWin (zip points (tail points))))
135 random:: (Physical a, Physical b) =>
136 Integer -> a -> SignalRep a b
137 random i s = waveform s (map toPhysical (rand i))
138 ramp:: (Physical a, Physical b) => a -> b -> SignalRep a b
140 let sig = linear (realdiv (fromPhysical v) (fromPhysical per)) (toPhysical 0.0)
141 in PieceContRep (Windows (cycle ([Window LocalZero (TimeEvent (fromPhysical per)) sig ])))
142 triangle:: (Physical a, Physical b) => a -> b -> SignalRep a b
144 let sl = realmul 2.0 (realdiv (fromPhysical v) (fromPhysical per))
145 qper = realdiv (fromPhysical v) 4.0
146 wins = (Window LocalZero (TimeEvent qper) (linear sl (toPhysical 0.0))) |>
147 (Window LocalZero (TimeEvent (realmul 2.0 qper)) (linear (- sl) v)) |>
148 (Window LocalZero (TimeEvent qper) (linear sl (toPhysical (- (fromPhysical v))))) |>
150 in PieceContRep (cycleWindows wins)
151 step:: (Physical a, Physical b) => a -> b -> SignalRep a b
152 step tr lvl = FunctionRep (\t -> if (fromPhysical t) < (fromPhysical tr) then (toPhysical 0.0) else lvl)
153 square:: (Physical a, Physical b) => a -> b -> SignalRep a b
155 let trans = realdiv (fromPhysical per) 2.0
156 nlvl = asTypeOf (toPhysical (- (fromPhysical lvl))) lvl
157 f t = if (fromPhysical t) < trans then lvl else nlvl
158 wins = Windows [Window LocalZero (TimeEvent (fromPhysical per)) (FunctionRep f)]
159 in PieceContRep (cycleWindows wins)
160 pulse:: (Physical a, Physical b) => a -> a -> b -> SignalRep a b
162 let tr = (fromPhysical st) + (fromPhysical wid)
163 f t = if (fromPhysical t) < (fromPhysical st) then (toPhysical 0.0)
164 else if (fromPhysical t) < tr then lvl else (toPhysical 0.0)
166 trap:: (Physical a, Physical b) => a -> a -> a -> a -> b ->
168 trap st r wid f lvl =
169 let stepSlope y y' t = realdiv (y' - y) (fromPhysical t)
170 bigwin = realmul 10000000 ((fromPhysical st) + (fromPhysical wid))
171 wins = Window LocalZero (TimeEvent (fromPhysical st)) (constant (toPhysical 0.0)) |>
172 Window LocalZero (TimeEvent (fromPhysical r)) (linear (stepSlope 0.0 (fromPhysical lvl) r) (toPhysical 0.0)) |>
173 Window LocalZero (TimeEvent (fromPhysical wid)) (constant lvl) |>
174 Window LocalZero (TimeEvent (fromPhysical f)) (linear (stepSlope (fromPhysical lvl) 0.0 f) lvl) |>
175 Window LocalZero (TimeEvent bigwin) (constant (toPhysical 0.0)) |>
178 expc:: (Physical a, Physical b) => Float -> SignalRep a b
179 expc damp = FunctionRep (\t -> toPhysical (exp (- (realmul (fromPhysical t) damp))))
180 data {- (Physical indep, Physical dep) => -} BasicSignal indep dep =
181 Overshoot {start_delay::indep,
184 oscillation::Frequency,
186 | Pulse_dc {start_delay::indep,
193 over::BasicSignal indep dep,
194 under::BasicSignal indep dep}
195 | Pulse_ac {start_delay::indep,
200 frequency::Frequency,
204 data {- (Eq a, Eq b) => -} Foo a b = Foo { x :: a, y :: b}
206 foo :: (Eq a, Eq b) => Foo a b
210 overshoot:: (Physical a, Physical b) => BasicSignal a b
211 overshoot = Overshoot{}
212 pulse_dc:: (Physical a, Physical b) => BasicSignal a b
213 pulse_dc = Pulse_dc {over = Overshoot{start_delay=toPhysical 0.0,
214 ringing=(toPhysical 0.0),
215 oscillation=toPhysical 1.0,
217 under = Overshoot{start_delay=toPhysical 0.0,
218 ringing=(toPhysical 0.0),
219 oscillation=toPhysical 1.0,
221 start_delay = toPhysical 0.0,
222 dc_offset = toPhysical 0.0}
224 pulse_ac:: (Physical a, Physical b) => BasicSignal a b
225 pulse_ac = Pulse_ac {dc_offset = toPhysical 0.0,
226 amplitude = toPhysical 0.0}
229 makeWin:: (Physical a, Physical b) => a -> a ->
230 SignalRep a b -> SignalRep a b
232 let wins = Window LocalZero (TimeEvent (fromPhysical st)) (constant (toPhysical 0.0)) |>
233 Window LocalZero (TimeEvent (fromPhysical wid)) sig |>
236 instance Signal BasicSignal where
237 toSig (Overshoot start_delay pulse_width ringing oscillation damp_fac) =
238 let ring = sine ringing oscillation 0.0
239 cond = asTypeOf (expc damp_fac) ring
241 temp:: (Physical a, Physical b) => SignalRep a b ->
242 SignalRep a b -> SignalRep a b
243 temp f g = FunctionRep (binop (*) (mapSignal f) (mapSignal g))
245 -- temp f g = asTypeOf (f * g) ring
246 wins = Window LocalZero (TimeEvent (fromPhysical start_delay)) (constant (toPhysical 0.0)) |>
247 Window LocalZero (TimeEvent (fromPhysical pulse_width)) sig |>
250 toSig Pulse_dc{ start_delay = start_delay
251 , rise_time = rise_time
252 , pulse_width = pulse_width
253 , fall_time = fall_time
254 , dc_offset = dc_offset
256 , amplitude = amplitude
260 let pul = trap start_delay rise_time pulse_width fall_time amplitude
261 so = toPhysical ((fromPhysical start_delay) + (fromPhysical rise_time))
262 su = toPhysical ((fromPhysical so) + (fromPhysical pulse_width) + (fromPhysical fall_time))
263 oversh = toSig over{start_delay=so}
264 undersh = toSig under{start_delay=su}
265 off = constant dc_offset
266 temp:: (Physical a, Physical b) => SignalRep a b ->
267 SignalRep a b -> SignalRep a b
268 temp f g = FunctionRep (binop (+) (mapSignal f) (mapSignal g))
269 sig = temp (temp (temp pul oversh) undersh) off
270 wins = (Window LocalZero (TimeEvent (fromPhysical period)) sig) |>
272 in PieceContRep (cycleWindows wins)
273 sumSig:: (Physical a, Physical b, Signal s, Signal s') =>
274 (s a b) -> (s' a b) -> SignalRep a b
276 let s1 t = fromPhysical (mapSignal f t)
277 s2 t = fromPhysical (mapSignal f' t)
278 in FunctionRep (\t -> toPhysical ((s1 t) + (s2 t)))
279 mulSig:: (Physical a, Physical b, Signal s, Signal s') =>
280 (s a b) -> (s' a b) -> SignalRep a b
282 let f1 t = fromPhysical (mapSignal f t)
283 f2 t = fromPhysical (mapSignal f' t)
284 in FunctionRep (\t -> toPhysical ((f1 t) * (f2 t)))
286 eventEps:: Float -> Float
287 eventEps x = let eps = realdiv x 1000 in if 0.01 < eps then 0.01 else eps