/// <summary> /// 連続時間フィルターの伝達関数を離散時間フィルターの伝達関数にBilinear transformする。 /// Discrete-time signal processing 3rd ed. pp.533 /// Benoit Boulet, 信号処理とシステムの基礎 pp.681-682 /// 三谷政昭, ディジタル・フィルタ理論&設計入門 pp.193 /// </summary> /// <param name="ps">連続時間フィルターの伝達関数</param> /// <returns>離散時間フィルターの伝達関数</returns> public FirstOrderComplexRationalPolynomial StoZ(FirstOrderComplexRationalPolynomial ps) { /* * n1s + n0 * ps = ────────── * d1s + d0 * * z^{-1} = zM とする。 * * Bilinear transform: * 2 1-zM * s → ─── * ────── * Td 1+zM * * 2/Td = kとすると以下のように書ける。 * * k(1-zM) * s → ─────── * 1+zM * * k(1-zM) n1*k(1-zM) + n0(1+zM) * n1 * ─────── + n0 ───────────────────── * 1+zM 1+zM n1*k(1-zM) + n0(1+zM) (n0-n1*k)zM + n0+n1*k * pz = ─────────────────── = ──────────────────────── = ───────────────────── = ───────────────────── * k(1-zM) d1*k(1-zM) + d0(1+zM) d1*k(1-zM) + d0(1+zM) (d0-d1*k)zM + d0+d1*k * d1 * ─────── + d0 ───────────────────── * 1+zM 1+zM * */ // 都合により、投入されるアナログフィルターの伝達関数psは、 // s' == s / ωcとしたs'についての式であることに注意!! double twoπ = 2.0 * Math.PI; double ωc = PrewarpωtoΩ(mMatchFreq * twoπ); double k = (1.0 / ωc) * (2.0 * mSampleFreq); var n0 = ps.N(0); var n1k = WWComplex.Mul(ps.N(1), k); var d0 = ps.D(0); var d1k = WWComplex.Mul(ps.D(1), k); var pz = new FirstOrderComplexRationalPolynomial( WWComplex.Sub(n0, n1k), WWComplex.Add(n0, n1k), WWComplex.Sub(d0, d1k), WWComplex.Add(d0, d1k)); return(pz); }
public static FirstOrderComplexRationalPolynomial LowpassToHighpass(FirstOrderComplexRationalPolynomial p) { /* * z^-1 → -z^-1に置き換える。 * * n1 z^-1 + n0 -n1 z^-1 + n0 * ────────────── → ─────────────── * d1 z^-1 + d0 -d1 z^-1 + d0 * */ var r = new FirstOrderComplexRationalPolynomial( p.N(1).Minus(), p.N(0), p.D(1).Minus(), p.D(0)); return(r); }
private static WWComplex InverseLaplaceTransformOne(FirstOrderComplexRationalPolynomial p, double t) { if (t < 0) { return(WWComplex.Zero()); } if (!p.N(1).EqualValue(WWComplex.Zero())) { // 約分によって分子が定数になるはずである。 throw new NotImplementedException(); } if (p.D(1).EqualValue(WWComplex.Zero()) && p.D(0).EqualValue(WWComplex.Unity())) { // 定数。 // 1 → δ(t) if (t == 0) { return(p.N(0)); } return(WWComplex.Zero()); } if (p.D(0).EqualValue(WWComplex.Zero())) { System.Diagnostics.Debug.Assert(!p.D(1).EqualValue(WWComplex.Zero())); // b/s → b*u(t) return(p.N(0)); } // b/(s-a) → b * exp(a * t) return(WWComplex.Mul(p.N(0), new WWComplex(Math.Exp(-t * p.D(0).real) * Math.Cos(-t * p.D(0).imaginary), Math.Exp(-t * p.D(0).real) * Math.Sin(-t * p.D(0).imaginary)))); }