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); } }
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); }
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); }
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); } }
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); } }
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; } }
/// <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); } }