JacobiPolynomials.java

  1. /* Copyright 2002-2022 CS GROUP
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS 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.  *   http://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.orekit.propagation.semianalytical.dsst.utilities;

  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;

  22. import org.hipparchus.CalculusFieldElement;
  23. import org.hipparchus.analysis.differentiation.FieldGradient;
  24. import org.hipparchus.analysis.differentiation.Gradient;
  25. import org.hipparchus.analysis.polynomials.PolynomialFunction;
  26. import org.hipparchus.analysis.polynomials.PolynomialsUtils;

  27. /** Provider of the Jacobi polynomials P<sub>l</sub><sup>v,w</sup>.
  28.  * <p>
  29.  * This class is used for {@link
  30.  * org.orekit.propagation.semianalytical.dsst.forces.DSSTTesseral
  31.  * tesseral contribution} computation.
  32.  * </p>
  33.  *
  34.  * @author Nicolas Bernard
  35.  * @since 6.1
  36.  */
  37. public class JacobiPolynomials {

  38.     /** Storage map. */
  39.     private static final Map<JacobiKey, List<PolynomialFunction>> MAP =
  40.             new HashMap<JacobiPolynomials.JacobiKey, List<PolynomialFunction>>();

  41.     /** Private constructor as class is a utility. */
  42.     private JacobiPolynomials() {
  43.     }

  44.     /** Returns the value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup> evaluated at γ.
  45.      * <p>
  46.      * This method is guaranteed to be thread-safe
  47.      * </p>
  48.      * @param l degree of the polynomial
  49.      * @param v v value
  50.      * @param w w value
  51.      * @param gamma γ value
  52.      * @return value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup>(γ)
  53.      * @since 10.2
  54.      */
  55.     public static Gradient getValue(final int l, final int v, final int w, final Gradient gamma) {

  56.         final List<PolynomialFunction> polyList;
  57.         synchronized (MAP) {

  58.             final JacobiKey key = new JacobiKey(v, w);

  59.             // Check the existence of the corresponding key in the map.
  60.             if (!MAP.containsKey(key)) {
  61.                 MAP.put(key, new ArrayList<PolynomialFunction>());
  62.             }

  63.             polyList = MAP.get(key);

  64.         }

  65.         final PolynomialFunction polynomial;
  66.         synchronized (polyList) {
  67.             // If the l-th degree polynomial has not been computed yet, the polynomials
  68.             // up to this degree are computed.
  69.             for (int degree = polyList.size(); degree <= l; degree++) {
  70.                 polyList.add(degree, PolynomialsUtils.createJacobiPolynomial(degree, v, w));
  71.             }
  72.             polynomial = polyList.get(l);
  73.         }

  74.         // compute value and derivative
  75.         return polynomial.value(gamma);

  76.     }

  77.     /** Returns the value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup> evaluated at γ.
  78.      * <p>
  79.      * This method is guaranteed to be thread-safe
  80.      * </p>
  81.      * @param <T> the type of the field elements
  82.      * @param l degree of the polynomial
  83.      * @param v v value
  84.      * @param w w value
  85.      * @param gamma γ value
  86.      * @return value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup>(γ)
  87.      * @since 10.2
  88.      */
  89.     public static <T extends CalculusFieldElement<T>> FieldGradient<T> getValue(final int l, final int v, final int w,
  90.                                                                             final FieldGradient<T> gamma) {

  91.         final List<PolynomialFunction> polyList;
  92.         synchronized (MAP) {

  93.             final JacobiKey key = new JacobiKey(v, w);

  94.             // Check the existence of the corresponding key in the map.
  95.             if (!MAP.containsKey(key)) {
  96.                 MAP.put(key, new ArrayList<PolynomialFunction>());
  97.             }

  98.             polyList = MAP.get(key);

  99.         }

  100.         final PolynomialFunction polynomial;
  101.         synchronized (polyList) {
  102.             // If the l-th degree polynomial has not been computed yet, the polynomials
  103.             // up to this degree are computed.
  104.             for (int degree = polyList.size(); degree <= l; degree++) {
  105.                 polyList.add(degree, PolynomialsUtils.createJacobiPolynomial(degree, v, w));
  106.             }
  107.             polynomial = polyList.get(l);
  108.         }

  109.         // compute value and derivative
  110.         return polynomial.value(gamma);

  111.     }

  112.     /** Inner class for Jacobi polynomials keys.
  113.      * <p>
  114.      * Please note that this class is not original content but is a copy from the
  115.      * Hipparchus library. This library is published under the
  116.      * Apache License, version 2.0.
  117.      * </p>
  118.      *
  119.      * @see org.hipparchus.analysis.polynomials.PolynomialsUtils
  120.      */
  121.     private static class JacobiKey {

  122.         /** First exponent. */
  123.         private final int v;

  124.         /** Second exponent. */
  125.         private final int w;

  126.         /** Simple constructor.
  127.          * @param v first exponent
  128.          * @param w second exponent
  129.          */
  130.         JacobiKey(final int v, final int w) {
  131.             this.v = v;
  132.             this.w = w;
  133.         }

  134.         /** Get hash code.
  135.          * @return hash code
  136.          */
  137.         @Override
  138.         public int hashCode() {
  139.             return (v << 16) ^ w;
  140.         }

  141.         /** Check if the instance represent the same key as another instance.
  142.          * @param key other key
  143.          * @return true if the instance and the other key refer to the same polynomial
  144.          */
  145.         @Override
  146.         public boolean equals(final Object key) {

  147.             if (!(key instanceof JacobiKey)) {
  148.                 return false;
  149.             }

  150.             final JacobiKey otherK = (JacobiKey) key;
  151.             return v == otherK.v && w == otherK.w;

  152.         }
  153.     }

  154. }