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.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.special.elliptic.legendre.LegendreEllipticIntegral;
22  import org.hipparchus.util.Binary64Field;
23  import org.hipparchus.util.FastMath;
24  import org.hipparchus.util.MathUtils;
25  import org.junit.Assert;
26  import org.junit.Test;
27  
28  public class FieldJacobiThetaTest {
29  
30      @Test
31      public void testNoConvergence() {
32          doTestNoConvergence(Binary64Field.getInstance());
33      }
34  
35      private <T extends CalculusFieldElement<T>> void doTestNoConvergence(Field<T> field) {
36          Assert.assertTrue(new FieldJacobiTheta<>(field.getZero().newInstance(Double.NaN)).values(field.getZero()).theta1().isNaN());
37      }
38  
39      @Test
40      public void testRealZero() {
41          doTestRealZero(Binary64Field.getInstance());
42      }
43  
44      private <T extends CalculusFieldElement<T>> void doTestRealZero(Field<T> field) {
45          final T k      = field.getZero().newInstance(0.675);
46          final T m      = k.multiply(k);
47          final T q      = LegendreEllipticIntegral.nome(m);
48          final T t3Ref  = field.getOne().add(q.
49                                              add(FastMath.pow(q, 4)).
50                                              add(FastMath.pow(q, 9)).
51                                              add(FastMath.pow(q, 16)).multiply(2));
52          final T theta3 = new FieldJacobiTheta<>(q).values(field.getZero()).theta3();
53          Assert.assertEquals(t3Ref.getReal(), theta3.getReal(), 1.0e-12);
54      }
55  
56      @Test
57      public void testQuarterPeriod() {
58          doTestQuarterPeriod(Binary64Field.getInstance());
59      }
60  
61      private <T extends CalculusFieldElement<T>> void doTestQuarterPeriod(Field<T> field) {
62          final T k      = field.getZero().newInstance(0.675);
63          final T m      = k.multiply(k);
64          final T q      = LegendreEllipticIntegral.nome(m);
65          final T theta3 = new FieldJacobiTheta<>(q).values(field.getZero()).theta3();
66          Assert.assertEquals(LegendreEllipticIntegral.bigK(m).getReal(),
67                              theta3.multiply(theta3).multiply(MathUtils.SEMI_PI).getReal(),
68                              1.0e-12);
69      }
70  
71      @Test
72      public void testEllipticFunctions() {
73          doTestEllipticFunctions(Binary64Field.getInstance());
74      }
75  
76      private <T extends CalculusFieldElement<T>> void doTestEllipticFunctions(Field<T> field) {
77  
78          final T                   z      = field.getZero().newInstance(1.3);
79          final T                   k      = field.getZero().newInstance(0.675);
80          final T                   m      = k.multiply(k);
81          final T                   q      =  LegendreEllipticIntegral.nome(m);
82          final T                   bigK   = LegendreEllipticIntegral.bigK(m);
83          final T                   zeta   = z.divide(bigK).multiply(MathUtils.SEMI_PI);
84          final FieldJacobiTheta<T> jt     = new FieldJacobiTheta<>(q);
85          final FieldTheta<T>       theta0 = jt.values(field.getZero());
86          final FieldTheta<T>       thetaZ = jt.values(zeta);
87  
88          // the theta functions are related to the elliptic functions
89          // see https://dlmf.nist.gov/22.2
90          final FieldJacobiElliptic<T> je = JacobiEllipticBuilder.build(k.multiply(k));
91          final FieldCopolarN<T> valuesN = je.valuesN(z);
92          final FieldCopolarD<T> valuesD = je.valuesD(z);
93          final FieldCopolarC<T> valuesC = je.valuesC(z);
94          final T t02 = theta0.theta2();
95          final T t03 = theta0.theta3();
96          final T t04 = theta0.theta4();
97          final T tz1 = thetaZ.theta1();
98          final T tz2 = thetaZ.theta2();
99          final T tz3 = thetaZ.theta3();
100         final T tz4 = thetaZ.theta4();
101         Assert.assertEquals(valuesN.sn().getReal(), t03.multiply(tz1)              .divide(t02.multiply(tz4)).getReal(),               3.0e-15);
102         Assert.assertEquals(valuesN.cn().getReal(), t04.multiply(tz2)              .divide(t02.multiply(tz4)).getReal(),               3.0e-15);
103         Assert.assertEquals(valuesN.dn().getReal(), t04.multiply(tz3)              .divide(t03.multiply(tz4)).getReal(),               3.0e-15);
104         Assert.assertEquals(valuesD.sd().getReal(), t03.multiply(t03).multiply(tz1).divide(t02.multiply(t04).multiply(tz3)).getReal(), 3.0e-15);
105         Assert.assertEquals(valuesD.cd().getReal(), t03.multiply(tz2)              .divide(t02.multiply(tz3)).getReal(),               3.0e-15);
106         Assert.assertEquals(valuesC.sc().getReal(), t03.multiply(tz1)              .divide(t04.multiply(tz2)).getReal(),               3.0e-15);
107 
108     }
109 
110 }