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.complex.Complex;
21  import org.hipparchus.complex.FieldComplex;
22  
23  /** Builder for algorithms compmuting Jacobi elliptic functions.
24   * <p>
25   * The Jacobi elliptic functions are related to elliptic integrals.
26   * </p>
27   * <p>
28   * There are different conventions to interpret the arguments of
29   * Jacobi elliptic functions. The first argument may be  the amplitude φ,
30   * but is more often the variable u (with sn(u) = sin(φ) and cn(u) = cos(φ)).
31   * The second argument  is either the modulus k or the parameter m with m = k².
32   * In Hipparchus, we adopted the convention to use u and m.
33   * </p>
34   * @since 2.0
35   */
36  public class JacobiEllipticBuilder {
37  
38      /** Threshold near 0 for using specialized algorithm. */
39      private static final double NEAR_ZERO = 1.0e-9;
40  
41      /** Threshold near 1 for using specialized algorithm. */
42      private static final double NEAR_ONE = 1.0 - NEAR_ZERO;
43  
44      /** Private constructor for utility class.
45       */
46      private JacobiEllipticBuilder() {
47          // nothing to do
48      }
49  
50      /** Build an algorithm for computing Jacobi elliptic functions.
51       * @param m parameter of the Jacobi elliptic function
52       * @return selected algorithm
53       */
54      public static JacobiElliptic build(final double m) {
55          if (m < 0) {
56              return new NegativeParameter(m);
57          } else if (m > 1) {
58              return new BigParameter(m);
59          } else if (m < NEAR_ZERO) {
60              return new NearZeroParameter(m);
61          } else if (m > NEAR_ONE) {
62              return new NearOneParameter(m);
63          } else {
64              return new BoundedParameter(m);
65          }
66      }
67  
68      /** Build an algorithm for computing Jacobi elliptic functions.
69       * @param m parameter of the Jacobi elliptic function
70       * @param <T> type of the field elements
71       * @return selected algorithm
72       */
73      public static <T extends CalculusFieldElement<T>> FieldJacobiElliptic<T> build(final T m) {
74          if (m.getReal() < 0) {
75              return new FieldNegativeParameter<>(m);
76          } else if (m.getReal() > 1) {
77              return new FieldBigParameter<>(m);
78          } else if (m.getReal() < NEAR_ZERO) {
79              return new FieldNearZeroParameter<>(m);
80          } else if (m.getReal() > NEAR_ONE) {
81              return new FieldNearOneParameter<>(m);
82          } else {
83              return new FieldBoundedParameter<>(m);
84          }
85      }
86  
87      /** Build an algorithm for computing Jacobi elliptic functions.
88       * @param m parameter of the Jacobi elliptic function
89       * @return selected algorithm
90       */
91      public static FieldJacobiElliptic<Complex> build(final Complex m) {
92          return new ComplexParameter(m);
93      }
94  
95      /** Build an algorithm for computing Jacobi elliptic functions.
96       * @param m parameter of the Jacobi elliptic function
97       * @param <T> type of the field elements
98       * @return selected algorithm
99       */
100     public static <T extends CalculusFieldElement<T>> FieldJacobiElliptic<FieldComplex<T>> build(final FieldComplex<T> m) {
101         return new FieldComplexParameter<>(m);
102     }
103 
104 }