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 }