Ejemplo n.º 1
0
        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();
            }
        }