public WWComplex ZeroNth(int nth) { switch (mMethod) { case Method.Bilinear: if (nth < mAfd.NumOfZeroes()) { return(mIIRBilinear.StoZ(mAfd.ZeroNth(nth)).Reciplocal()); } else { // 零は z==-1にある。 return(new WWComplex(-1, 0)); } default: return(mIIRiim.ZeroNth(nth)); } }
void CalcFilterCompleted(object sender, RunWorkerCompletedEventArgs e) { mMainPanel.IsEnabled = true; mTextBlockCalculating.Visibility = System.Windows.Visibility.Collapsed; mTextBoxLog.Clear(); var r = e.Result as BackgroundCalcResult; if (!r.success) { MessageBox.Show(r.message); return; } AddLog(string.Format("Order={0}\n", mAfd.Order())); // 伝達関数の式をログに出力。 AddLog("Transfer function (factorized, normalized) H(s) = "); AddLog(string.Format("{0:G4}", mAfd.NumeratorConstant())); for (int i = 0; i < mAfd.NumOfZeroes(); ++i) { AddLog(string.Format(" (s + {0})", WWComplex.Minus(mAfd.ZeroNth(i)))); } AddLog(" /"); for (int i = 0; i < mAfd.NumOfPoles(); ++i) { AddLog(string.Format(" (s + {0})", WWComplex.Minus(mAfd.PoleNth(i)))); } AddLog("\n"); { // Show expanded Transfer function var zeroList = new WWComplex[mAfd.NumOfZeroes()]; for (int i = 0; i < mAfd.NumOfZeroes(); ++i) { zeroList[i] = mAfd.ZeroNth(i); } var poleList = new WWComplex[mAfd.NumOfPoles()]; for (int i = 0; i < mAfd.NumOfPoles(); ++i) { poleList[i] = mAfd.PoleNth(i); } var numer = WWPolynomial.RootListToCoeffList(zeroList, new WWComplex(mAfd.NumeratorConstant(), 0)); var denom = WWPolynomial.RootListToCoeffList(poleList, WWComplex.Unity()); AddLog("Transfer function (expanded, normalized) H(s) = {"); AddLog(new ComplexPolynomial(numer).ToString("s")); AddLog(" } / {"); AddLog(new ComplexPolynomial(denom).ToString("s")); AddLog(" }\n"); } AddLog(string.Format("Transfer function with real coefficients H(s) = ")); for (int i = 0; i < mAfd.RealPolynomialCount(); ++i) { AddLog(mAfd.RealPolynomialNth(i).ToString("(s/ωc)")); if (i != mAfd.RealPolynomialCount() - 1) { AddLog(" + "); } } AddLog("\n"); // インパルス応答の式をログに出力。 var H_s = new List <FirstOrderComplexRationalPolynomial>(); AddLog(("Impulse Response (frequency normalized): h(t) = ")); for (int i = 0; i < mAfd.HPfdCount(); ++i) { var p = mAfd.HPfdNth(i); H_s.Add(p); if (!p.N(1).EqualValue(WWComplex.Zero())) { throw new System.NotImplementedException(); } if (p.D(1).EqualValue(WWComplex.Zero()) && p.D(0).EqualValue(WWComplex.Unity())) { // 1 → δ(t) AddLog(string.Format("{0:G4} * δ(t)", p.N(0))); } else if (p.D(0).EqualValue(WWComplex.Zero())) { // b/s → b*u(t) AddLog(string.Format("{0:G4} * u(t)", p.N(0))); } else { // b/(s-a) ⇒ b * exp(t * a) AddLog(string.Format("({0}) * e^ {{ t * ({1}) }}", p.N(0), WWComplex.Minus(p.D(0)))); } if (i != mAfd.HPfdCount() - 1) { AddLog(" + "); } } AddLog("\n"); // 周波数応答グラフに伝達関数をセット。 mFrequencyResponseS.TransferFunction = mAfd.TransferFunction; mFrequencyResponseS.Update(); // Pole-Zeroプロットに極と零の位置をセット。 mPoleZeroPlotS.ClearPoleZero(); double scale = mAfd.PoleNth(0).Magnitude(); if (0 < mAfd.NumOfZeroes() && scale < mAfd.ZeroNth(0).Magnitude()) { scale = mAfd.ZeroNth(0).Magnitude(); } mPoleZeroPlotS.SetScale(scale); for (int i = 0; i < mAfd.NumOfPoles(); ++i) { var p = mAfd.PoleNth(i); mPoleZeroPlotS.AddPole(p); } for (int i = 0; i < mAfd.NumOfZeroes(); ++i) { var p = mAfd.ZeroNth(i); mPoleZeroPlotS.AddZero(p); } mPoleZeroPlotS.TransferFunction = mAfd.PoleZeroPlotTransferFunction; mPoleZeroPlotS.Update(); // 時間ドメインプロットの更新。 mTimeDomainPlot.ImpulseResponseFunction = mAfd.ImpulseResponseFunction; mTimeDomainPlot.StepResponseFunction = mAfd.UnitStepResponseFunction; mTimeDomainPlot.TimeScale = mAfd.TimeDomainFunctionTimeScale; mTimeDomainPlot.Update(); // アナログ回路表示。 AddLog(string.Format("Analog Filter Stages = {0}\n", mAfd.RealPolynomialCount())); mAnalogFilterCircuit.Clear(); { groupBoxAFC.Visibility = System.Windows.Visibility.Visible; mAnalogFilterCircuit.CutoffFrequencyHz = mFc; for (int i = 0; i < mAfd.RealPolynomialCount(); ++i) { mAnalogFilterCircuit.Add(mAfd.RealPolynomialNth(i)); } mAnalogFilterCircuit.AddFinished(); mAnalogFilterCircuit.Update(); } }