View Javadoc
1   /*
2    * Licensed to the Hipparchus project under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.hipparchus.special.elliptic.jacobi;
18  
19  import org.hipparchus.complex.Complex;
20  import org.hipparchus.special.elliptic.legendre.LegendreEllipticIntegral;
21  import org.hipparchus.util.FastMath;
22  import org.hipparchus.util.MathUtils;
23  import org.junit.jupiter.api.Test;
24  
25  import static org.junit.jupiter.api.Assertions.assertEquals;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  class JacobiThetaTest {
29  
30      @Test
31      void testNoConvergence() {
32          assertTrue(new JacobiTheta(Double.NaN).values(Complex.ZERO).theta1().isNaN());
33      }
34  
35      @Test
36      void testRealZero() {
37          final double           k      = 0.675;
38          final double           m      = k * k;
39          final double           q      = LegendreEllipticIntegral.nome(m);
40          final double           t3Ref  = 1 + 2 * (q + FastMath.pow(q, 4) + FastMath.pow(q, 9) + FastMath.pow(q, 16));
41          final double           theta3 = new JacobiTheta(q).values(Complex.ZERO).theta3().getRealPart();
42          assertEquals(t3Ref, theta3, 1.0e-12);
43      }
44  
45      @Test
46      void testWolframAlpha() {
47          final Theta theta = new JacobiTheta(0.25).values(new Complex(2, 1));
48          assertEquals( 2.21896723745108057500, theta.theta1().getRealPart(),      1.0e-15);
49          assertEquals(-1.56332891301806559779, theta.theta1().getImaginaryPart(), 1.0e-15);
50          assertEquals(-0.07520617984531674751, theta.theta2().getRealPart(),      1.0e-15);
51          assertEquals(-1.24993491278546664559, theta.theta2().getImaginaryPart(), 1.0e-15);
52          assertEquals(-0.25931139474579522847, theta.theta3().getRealPart(),      1.0e-15);
53          assertEquals( 1.16230083178353441578, theta.theta3().getImaginaryPart(), 1.0e-15);
54          assertEquals( 2.19722649038852886551, theta.theta4().getRealPart(),      1.0e-15);
55          assertEquals(-1.58416769196278632848, theta.theta4().getImaginaryPart(), 1.0e-15);
56      }
57  
58      @Test
59      void testQuarterPeriod() {
60          final double           k      = 0.675;
61          final double           m      = k * k;
62          final double           q      = LegendreEllipticIntegral.nome(m);
63          final double           theta3 = new JacobiTheta(q).values(Complex.ZERO).theta3().getRealPart();
64          assertEquals(LegendreEllipticIntegral.bigK(m), MathUtils.SEMI_PI * theta3 * theta3, 1.0e-12);
65      }
66  
67      @Test
68      void testEllipticFunctions() {
69  
70          final double      z      = 1.3;
71          final double      k      = 0.675;
72          final double      m      = k * k;
73          final double      q      = LegendreEllipticIntegral.nome(m);
74          final double      bigK   = LegendreEllipticIntegral.bigK(m);
75          final double      zeta   = MathUtils.SEMI_PI * z / bigK;
76          final JacobiTheta jt     = new JacobiTheta(q);
77          final Theta       theta0 = jt.values(Complex.ZERO);
78          final Theta       thetaZ = jt.values(new Complex(zeta));
79  
80          // the theta functions are related to the elliptic functions
81          // see https://dlmf.nist.gov/22.2
82          final JacobiElliptic je = JacobiEllipticBuilder.build(m);
83          final CopolarN valuesN = je.valuesN(z);
84          final CopolarD valuesD = je.valuesD(z);
85          final CopolarC valuesC = je.valuesC(z);
86          final double t02 = theta0.theta2().getRealPart();
87          final double t03 = theta0.theta3().getRealPart();
88          final double t04 = theta0.theta4().getRealPart();
89          final double tz1 = thetaZ.theta1().getRealPart();
90          final double tz2 = thetaZ.theta2().getRealPart();
91          final double tz3 = thetaZ.theta3().getRealPart();
92          final double tz4 = thetaZ.theta4().getRealPart();
93          assertEquals(valuesN.sn(), t03 * tz1       / (t02 * tz4),       1.0e-15);
94          assertEquals(valuesN.cn(), t04 * tz2       / (t02 * tz4),       1.0e-15);
95          assertEquals(valuesN.dn(), t04 * tz3       / (t03 * tz4),       1.0e-15);
96          assertEquals(valuesD.sd(), t03 * t03 * tz1 / (t02 * t04 * tz3), 1.0e-15);
97          assertEquals(valuesD.cd(), t03 * tz2       / (t02 * tz3),       1.0e-15);
98          assertEquals(valuesC.sc(), t03 * tz1       / (t04 * tz2),       1.0e-15);
99  
100     }
101 
102 }