public void Creation() { const double fd = 0.5; // Гц // Частота дискретизации const double dt = 1 / fd; // 2с // Период дискретизации const double fp = 0.05; // Гц // Граничная частота полосы пропускания const double fs = 0.15; // Гц // Граничная частота полосы запирания Assert.IsTrue(fp < fs); Assert.IsTrue(fp < fd / 2); //const double wp = Consts.pi2 * fp * dt; // 0.628318530717959 рад/с //const double ws = Consts.pi2 * fs * dt; // 1.884955592153876 рад/с const double Rp = 1; // Неравномерность в полосе пропускания (дБ) const double Rs = 30; // Неравномерность в полосе пропускания (дБ) var eps_p = (10d.Pow(Rp / 10) - 1).Sqrt(); var eps_s = (10d.Pow(Rs / 10) - 1).Sqrt(); Assert.That.Value(eps_p).IsEqual(0.50884713990958752); Assert.That.Value(eps_s).IsEqual(31.606961258558215); var Gp = (-Rp).From_dB(); var Gs = (-Rs).From_dB(); Assert.That.Value(Gp).IsEqual(0.89125093813374556); Assert.That.Value(Gs).IsEqual(0.031622776601683791); Assert.That.Value(Gp.In_dB()).IsEqual(-1, 4.67e-15); Assert.That.Value(Gs.In_dB()).IsEqual(-30); var Fp = DigitalFilter.ToAnalogFrequency(fp, dt); // Частота пропускания аналогового прототипа var Fs = DigitalFilter.ToAnalogFrequency(fs, dt); // Частота подавления аналогового прототипа Assert.That.Value(Fp).IsEqual(0.051712575763384123); Assert.That.Value(Fs).IsEqual(0.2190579862253032); var Wp = Consts.pi2 * Fp; var Ws = Consts.pi2 * Fs; var k_eps = eps_s / eps_p; var k_W = Ws / Wp; Assert.That.Value(k_eps).GreaterThan(0); Assert.That.Value(k_W).GreaterThan(0); var double_n = Log(k_eps) / Log(k_W); // Порядок фильтра var N = (int)double_n; if (double_n - N > 0) { N += 1; } Assert.That.Value(N).IsEqual(3); var L = N / 2; var r = N % 2; Assert.That.Value(L).IsEqual(1); Assert.That.Value(r).IsEqual(1); Assert.That.Value(2 * L + r).IsEqual(N); var alpha = eps_p.Pow(-1d / N); Assert.That.Value(alpha).IsEqual(1.2525763881810263); var th0 = PI / N; var poles = new Complex[N]; if (r != 0) { poles[0] = -alpha; } for (var i = r; i < poles.Length; i += 2) { var w = th0 * (i + 1 - r - 0.5); poles[i] = (-alpha * Sin(w), alpha *Cos(w)); poles[i + 1] = poles[i].ComplexConjugate; } Assert.That.Collection(poles).IsEqualTo( -1.2525763881810263, (-0.62628819409051306, 1.0847629723453271), (-0.62628819409051306, -1.0847629723453271) ); var translated_poles = poles.ToArray(p => p * Wp) .AssertThatCollection() .IsEqualTo( -0.40698673955629, (-0.20349336977814494, 0.35246085545914824), (-0.20349336977814494, -0.35246085545914824)) .ActualValue; var z_poles = translated_poles.ToArray(p => DigitalFilter.ToZ(p, dt)) .AssertThatCollection() .IsEqualTo( 0.42147750491999925, (0.53055357928176117, 0.44824528113449957), (0.53055357928176117, -0.44824528113449957)) .AllItems(z_pole => z_pole.Where(z => z.Abs < 1)) .ActualValue; var kz = DigitalFilter.GetNormalizeCoefficient(translated_poles, dt) .AssertThanValue() .IsEqual(0.45194421873401691) .ActualValue; var WpN = Wp.Pow(N) .AssertThanValue() .IsEqual(0.034302685030761955) .ActualValue; var k = WpN * kz / eps_p; Assert.That.Value(k).IsEqual(0.030466713814017582); var b = Range(0, N + 1).ToArray(i => k * BinomialCoefficient(N, i)); Assert.That.Collection(b).IsEqualTo(new[] { 1 * k, 3 * k, 3 * k, 1 * k }); var a_complex = Polynom.Array.GetCoefficientsInverted((Complex[])z_poles); Assert.That.Collection(a_complex) .CountEquals(4) .AllItems(a_value => a_value.Where(z => z.Im).IsEqual(0, 1e-16)); var a = a_complex.ToRe() ?? throw new AssertFailedException("Отсутствует ссылка на массив вещественных значений"); Assert.That.Collection(a).ValuesAreEqual( 1, -1.4825846634835216, 0.92964373019213786, -0.20332535619647568 ); var filter = new DSP.Filters.ButterworthLowPass(dt, fp, fs, Gp, Gs); Assert.That.Collection(filter.A).IsEqualTo(a, 1e-15); Assert.That.Collection(filter.B).IsEqualTo(b, 1e-16); }
public void Creation_fp500_ps1500_fd_5000() { const double fp = 500; // Гц // Граничная частота полосы пропускания const double fs = 1500; // Гц // Граничная частота полосы запирания const double fd = 5000; // Гц // Частота дискретизации const double dt = 1 / fd; // 2с // Период дискретизации const double Rp = 1; // Неравномерность в полосе пропускания (дБ) const double Rs = 30; // Неравномерность в полосе пропускания (дБ) var Gp = (-Rp).From_dB(); var Gs = (-Rs).From_dB(); var eps_p = (10d.Pow(Rp / 10) - 1).Sqrt(); var eps_s = (10d.Pow(Rs / 10) - 1).Sqrt(); var Fp = DigitalFilter.ToAnalogFrequency(fp, dt); // Частота пропускания аналогового прототипа var Fs = DigitalFilter.ToAnalogFrequency(fs, dt); // Частота подавления аналогового прототипа var k_eps = eps_s / eps_p; var k_W = Fs / Fp; var double_n = Log(k_eps) / Log(k_W); var N = (int)double_n; if (double_n - N > 0) { N += 1; } var L = N / 2; var r = N % 2; var alpha = eps_p.Pow(-1d / N); var th0 = PI / N; var poles = new Complex[N]; if (r != 0) { poles[0] = -alpha; } for (var i = r; i < poles.Length; i += 2) { var w = th0 * (i + 1 - r - 0.5); poles[i] = (-alpha * Sin(w), alpha *Cos(w)); poles[i + 1] = poles[i].ComplexConjugate; } var translated_poles = poles.ToArray(p => p * Consts.pi2 * Fp); var z_poles = translated_poles.ToArray(p => DigitalFilter.ToZ(p, dt)); var kz = DigitalFilter.GetNormalizeCoefficient(translated_poles, dt); var WpN = (Consts.pi2 * Fp).Pow(N); var k = WpN * kz / eps_p; var b = Range(0, N + 1).ToArray(i => k * BinomialCoefficient(N, i)); var a_complex = Polynom.Array.GetCoefficientsInverted(z_poles); var a = a_complex.ToRe() ?? throw new AssertFailedException("Отсутствует ссылка на массив вещественных значений"); var filter = new DSP.Filters.ButterworthLowPass(dt, fp, fs, Gp, Gs); Assert.That.Value(filter.Order).IsEqual(N); var tr_k = filter.GetTransmissionCoefficient(fs, dt).Abs.In_dB(); Assert.That.Collection(filter.A).IsEqualTo(a, 3e-12); Assert.That.Collection(filter.B).IsEqualTo(b, 1e-16); }