public IIRFilterBlockReal(RealRationalPolynomial p) { // 分母の定数項が1.0になるようにスケールする p = p.ScaleAllCoeffs(1.0f / p.D(0)); mH = p; mMaxOrder = p.NumerDegree(); if (mMaxOrder < p.DenomDegree()) { mMaxOrder = p.DenomDegree(); } mB = new double[mMaxOrder + 1]; for (int i = 0; i <= p.NumerDegree(); ++i) { mB[i] = p.N(i); } mA = new double[mMaxOrder + 1]; mA[0] = p.D(0); for (int i = 1; i < mA.Length; ++i) { mA[i] = -p.D(i); } mV = new double[mMaxOrder + 1]; }
public IIRFilterGraph CreateIIRFilterGraph() { IIRFilterGraph iirFilter = null; // フィルターを作る。 // 実数係数版の多項式を使用。 switch (mMethod) { case Method.ImpulseInvarianceMinimumPhase: iirFilter = new IIRFilterSerial(); break; case Method.ImpulseInvarianceMixedPhase: case Method.Bilinear: iirFilter = new IIRFilterParallel(); break; } switch (mMethod) { case Method.Bilinear: for (int i = 0; i < mIIRBilinear.RealHzCount(); ++i) { RealRationalPolynomial p = mIIRBilinear.RealHz(i); Console.WriteLine("{0}", p.ToString("(z)^(-1)")); iirFilter.Add(p); } break; case Method.ImpulseInvarianceMinimumPhase: case Method.ImpulseInvarianceMixedPhase: for (int i = 0; i < mIIRiim.RealHzCount(); ++i) { RealRationalPolynomial p = mIIRiim.RealHz(i); Console.WriteLine("{0}", p.ToString("(z)^(-1)")); iirFilter.Add(p); } break; } return(iirFilter); }
/// <summary> /// 多項式pは直列接続される。(p同士を掛けていく感じになる) /// </summary> public void Add(RealRationalPolynomial p) { var b = new IIRFilterBlockReal(p); mFilterBlockList.Add(b); }
/// <summary> /// Addし終わったら呼ぶ。 /// </summary> public void Calc() { // mComplexHzListに1次の関数が入っている。 // 係数が全て実数のmRealHzListを作成する。 // mRealHzListは、多項式の和を表現する。 mRealHzList.Clear(); for (int i = 0; i < mComplexHzList.Count / 2; ++i) { var p0 = mComplexHzList[i]; var p1 = mComplexHzList[mComplexHzList.Count - 1 - i]; var p = WWPolynomial.Add(p0, p1).ToRealPolynomial(); mRealHzList.Add(p); } if ((mComplexHzList.Count & 1) == 1) { // 1次の項。 var p = mComplexHzList[mComplexHzList.Count / 2]; mRealHzList.Add(new RealRationalPolynomial( new double[] { p.N(0).real, p.N(1).real }, new double[] { p.D(0).real, p.D(1).real })); } var stopbandGain = WWComplex.Zero(); if (mFilterType == FilterType.Lowpass) { foreach (var p in mRealHzList) { stopbandGain = WWComplex.Add(stopbandGain, p.Evaluate(WWComplex.Unity())); } } else { foreach (var p in mRealHzList) { stopbandGain = WWComplex.Add(stopbandGain, p.Evaluate(new WWComplex(-1, 0))); } } // DCゲインが1になるようにHzをスケールする。 for (int i = 0; i < mRealHzList.Count; ++i) { var p = mRealHzList[i]; mRealHzList[i] = p.ScaleNumerCoeffs(1.0 / stopbandGain.real); } stopbandGain = WWComplex.Zero(); foreach (var p in mRealHzList) { stopbandGain = WWComplex.Add(stopbandGain, p.Evaluate(WWComplex.Unity())); } Console.WriteLine("DC gain={0}", stopbandGain); TransferFunction = (WWComplex z) => { return(TransferFunctionValue(z)); }; mHzCombined = new RealRationalPolynomial(mRealHzList[0]); for (int i = 1; i < mRealHzList.Count; ++i) { var p = mRealHzList[i]; mHzCombined = WWPolynomial.Add(mHzCombined, p); } mHzCombined = mHzCombined.ScaleAllCoeffs(1.0 / mHzCombined.D(0)); }