Пример #1
0
        public void EllipticFTest()
        {
            var z = new[] {
                new Complex(-0.670791254938757, -0.0938159212065481),
                new Complex(0.528053930350357, -1.07956370130938),
                new Complex(-0.557287707188084, -1.00272777341254),
                new Complex(0.320745728918526, 0.287620039090474),
                new Complex(-0.420904792797892, 0.642254696882941),
                new Complex(0.109863468987495, -0.47809418429494),
                new Complex(-0.272688296113657, 0.197822903078282),
                new Complex(10.9863468987495, -0.47809418429494),
                new Complex(-27.2688296113657, 0.197822903078282),
            };

            var expected = new[] {
                new Complex(-0.68620842267039771730, -0.10047616775855015460),
                new Complex(0.42868733998557565682, -1.05995343584072013101),
                new Complex(-0.46942504702869457356, -1.00008738595868835155),
                new Complex(0.31819382130927205251, 0.29124965412479359813),
                new Complex(-0.39580478305810881056, 0.64709397408138872245),
                new Complex(0.10569294199103250250, -0.47295612599211204389),
                new Complex(-0.27204914758137346116, 0.19984298803088524405),
                new Complex(12.12391310952531579389, -0.5977215792388405620),
                new Complex(-30.1535374477487750443, 0.22663693321479046126),
            };

            for (int i = 0; i < expected.Length; i++)
            {
                Complex f;
                f = Elliptic.F(z[i], 0.333);
                var err = (f - expected[i]).Magnitude;
                Assert.IsTrue(err < 1e-14);
            }
        }
Пример #2
0
        public void EllipticFLargeArgumentTest()
        {
            var x = 1436.699529559065124036301546242965863291805609504612854879;
            var f = Elliptic.F(1000, .8);

            Assert.IsTrue(Math.Abs(x - f) < 1e-12);
            f = Elliptic.FDouble(.8)(1000);
            Assert.IsTrue(Math.Abs(x - f) < 1e-12);
        }
Пример #3
0
        public void EllipticFModulusOneHalfTest()
        {
            double f;
            var    e = Elliptic.FDouble(Math.Sqrt(0.5));

            f = Elliptic.F(.5, Math.Sqrt(0.5));
            Assert.IsTrue(Math.Abs(f - 0.51516665702885808770) < 1e-12);
            f = e(0);
            Assert.AreEqual(0, f);
            f = e(1);
            Assert.IsTrue(Math.Abs(f - 1.1310061601574670032) < 1e-12);
        }
Пример #4
0
        public void EllipticFMatchesComplexTest()
        {
            var rand = new Random("EllipticFMatchesComplexTest".GetHashCode());

            for (int i = 0; i < 100; i++)
            {
                var m   = rand.NextDouble();
                var efm = Elliptic.FComplex(m);
                var z   = RandomZ(rand);
                var f1  = Elliptic.F(z, m);
                var f2  = efm(z);
                Assert.AreEqual(f1, f2);
            }
        }
Пример #5
0
        public void EllipticFMatchesDoubleTest()
        {
            var rand = new Random("EllipticFMatchesDoubleTest".GetHashCode());

            for (int i = 0; i < 100; i++)
            {
                var m   = rand.NextDouble();
                var efm = Elliptic.FDouble(m);
                var x   = Math.Sqrt(-2 * Math.Log(rand.NextDouble())) * Math.Cos(Math.PI * rand.NextDouble());
                var f1  = Elliptic.F(x, m);
                var f2  = efm(x);
                Assert.AreEqual(f1, f2);
            }
        }
Пример #6
0
        public override void GetAnalogPrototype(Coefficient[] coefs)
//		public void GetAnalogPrototype2(Coefficient[] coefs)
        {
            double m1  = this.m1;
            double m1p = 1 - this.m1;

            double Kk1  = Elliptic.K(m1);
            double Kk1p = Elliptic.K(m1p);

            double m  = Elliptic.InverseQ(Math.Exp(-Math.PI * Kk1p / (this.order * Kk1)));
            double mp = 1 - m;
            double Kk = Elliptic.K(m);

            double phi, sn_p, cn_p, dn_p;
            double v = Elliptic.F(Math.Atan(1 / this.epsilon), m1p) * Kk / (this.order * Kk1);

            Elliptic.Jacobi(v, mp, out phi, out sn_p, out cn_p, out dn_p);

            for (int i = this.order - 1, j = 0; i > 0; i -= 2, ++j)
            {
                Coefficient coef = coefs[j];

                double sn, cn, dn;
                double u = Kk * (double)i / this.order;
                Elliptic.Jacobi(u, m, out phi, out sn, out cn, out dn);

                double denom = 1 - dn * dn * sn_p * sn_p;
                double re    = -cn * dn * sn_p * cn_p / denom;
                double im    = -sn * dn_p / denom;

                double alpha = -2 * re;
                double beta  = re * re + im * im;
                double gamma = 1 / (m * sn * sn);

                coef.a[0] = 1; coef.a[1] = alpha / beta; coef.a[2] = 1 / beta;
                coef.b[0] = 1; coef.b[1] = 0;            coef.b[2] = 1 / gamma;
            }

            if ((this.order & 1) == 1)
            {
                Coefficient coef = coefs[this.order / 2];

                double denom = 1 - sn_p * sn_p;
                double re    = -sn_p * cn_p / denom;

                coef.a[0] = 1; coef.a[1] = -1 / re; coef.a[2] = 0;
                coef.b[0] = 1; coef.b[1] = 0;       coef.b[2] = 0;
            }
        }
Пример #7
0
        /// <summary>
        /// フィルタの零点/極を計算。
        /// </summary>
        /// <param name="roots">零点/極一覧の格納先</param>
        public override void GetZeroPole(ZeroPole[] roots)
        {
            double m1  = this.m1;
            double m1p = 1 - this.m1;

            double Kk1  = Elliptic.K(m1);
            double Kk1p = Elliptic.K(m1p);

            double temp1 = -Math.PI * Kk1p / (this.order * Kk1);
            double temp2 = Math.Exp(temp1);

            double m  = Elliptic.InverseQ(Math.Exp(-Math.PI * Kk1p / (this.order * Kk1)));
            double mp = 1 - m;
            double k  = Math.Sqrt(m);
            double Kk = Elliptic.K(m);

            double Kkp   = Elliptic.K(mp);
            double temp3 = (Kk / Kkp) / (Kk1 / Kk1p);

            double phi, sn_p, cn_p, dn_p;
            double v = Elliptic.F(Math.Atan(1 / this.epsilon), m1p) * Kk / (this.order * Kk1);

            Elliptic.Jacobi(v, mp, out phi, out sn_p, out cn_p, out dn_p);

            for (int i = this.order - 1, j = 0; i > 0; i -= 2, ++j)
            {
                double sn, cn, dn;
                double u = Kk * (double)i / this.order;
                Elliptic.Jacobi(u, m, out phi, out sn, out cn, out dn);

                double denom = 1 - dn * dn * sn_p * sn_p;
                double re    = -cn * dn * sn_p * cn_p / denom;
                double im    = -sn * dn_p / denom;

                roots[j].zero = new Root(Root.Type.Complex, 0, 1 / (k * sn));
                roots[j].pole = new Root(Root.Type.Complex, re, im);
            }

            if ((this.order & 1) == 1)
            {
                double denom = 1 - sn_p * sn_p;
                double re    = -sn_p * cn_p / denom;

                roots[this.order / 2].zero = new Root(Root.Type.None, 0, 0);
                roots[this.order / 2].pole = new Root(Root.Type.Single, re, 0);
            }
        }