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