import Data.Complex
import Bode
---- Dual representation of 2-terminals.
-- "Half" two-terminal: 2 primitive elements, one composition.
data HTT a = Resistive a -- V = R I ; I = G V
| Reactive a -- V = L dI/dt ; I = C dV/dt
| Composite (TT a) (TT a) -- V1 + V2 (ser) ; I1 + I2 (par)
deriving (Show, Eq)
-- A two-terminal is a dualized HTT.
data TT a = Primal (HTT a) -- keep duals
| Dual (HTT a) -- flip duals (invert)
deriving (Show, Eq)
dual (Primal htt) = Dual htt
dual (Dual htt) = Primal htt
-- The main idea of the dual representation is generality. One
-- consequence is that building a s-parameterized
-- impedance/admittance/transfer function is straightforward.
trans :: (RealFloat a) => (TT a) -> (Complex a) -> (Complex a)
trans = flip t'' where
t'' s = t' where
t' (Dual htt) = 1 / (t htt)
t' (Primal htt) = t htt
t (Resistive v) = v :+ 0
t (Reactive v) = (v :+ 0) * s
t (Composite x y) = (t' x) + (t' y)
---- Absolute representation of 2-terminals in terms of dual rep.
-- To represent networks we need to tag the TT to indicate which one
-- of Impedance or Admittance it represents.
data ATT a = Impedance (TT a)
| Admittance (TT a)
deriving (Show, Eq)
-- Primitive absolute elements are constructed as I/A tagged Primal TTs.
-- Resistive: Impedance / Admittance independent of frequency.
res r = Impedance (Primal (Resistive r)) -- resistor (Ohms)
cnd g = Admittance (Primal (Resistive g)) -- conductor (Siemens,Mhos)
-- Reactive: Impedance / Admittance proportional to frequency.
ind l = Impedance (Primal (Reactive l)) -- inductor (Henry)
cap c = Admittance (Primal (Reactive c)) -- capacitor (Farad)
-- Project absolute ATT to relative TT.
imp :: (ATT a) -> (TT a)
adm :: (ATT a) -> (TT a)
imp (Impedance tt) = tt
imp (Admittance tt) = dual tt
adm = dual . imp
-- Primitive absolute 2-terminal operations are constructed in terms
-- of a Primal Composite operation.
ser a b = Impedance (Primal (Composite (imp a) (imp b)))
par a b = Admittance (Primal (Composite (adm a) (adm b)))
j x = (0 :+ x)
-- Voltage divider
divider a b s = a' / (a' + b') where
a' = trans (imp a) s
b' = trans (imp b) s
-- More useful units
ucap = cap . (0.000001 *)
ncap = ucap . (0.001 *)
pcap = ncap . (0.001 *)
kres = res . (1000 *)
-- Transfer function of the impedance of a parallel resistor and capacitor.
test1 = trans $ imp (par (kres 20) (ncap 50))
-- bodeplot test1