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 }