JacobiPolynomials.java

  1. /* Copyright 2002-2020 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.RealFieldElement;
  23. import org.hipparchus.analysis.differentiation.DerivativeStructure;
  24. import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
  25. import org.hipparchus.analysis.differentiation.FieldGradient;
  26. import org.hipparchus.analysis.differentiation.Gradient;
  27. import org.hipparchus.analysis.polynomials.PolynomialFunction;
  28. import org.hipparchus.analysis.polynomials.PolynomialsUtils;

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

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

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

  46.     /** Returns the value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup> evaluated at γ.
  47.      * <p>
  48.      * This method is guaranteed to be thread-safe
  49.      * </p>
  50.      * @param l degree of the polynomial
  51.      * @param v v value
  52.      * @param w w value
  53.      * @param gamma γ value
  54.      * @return value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup>(γ)
  55.      * @deprecated as of 10.2, replaced by {@link #getValue(int, int, int, Gradient)}
  56.      */
  57.     @Deprecated
  58.     public static DerivativeStructure getValue(final int l, final int v, final int w, final DerivativeStructure gamma) {

  59.         final List<PolynomialFunction> polyList;
  60.         synchronized (MAP) {

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

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

  66.             polyList = MAP.get(key);

  67.         }

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

  77.         // compute value and derivative
  78.         return polynomial.value(gamma);

  79.     }

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

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

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

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

  99.             polyList = MAP.get(key);

  100.         }

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

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

  112.     }

  113.     /** Returns the value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup> evaluated at γ.
  114.      * <p>
  115.      * This method is guaranteed to be thread-safe
  116.      * </p>
  117.      * @param <T> the type of the field elements
  118.      * @param l degree of the polynomial
  119.      * @param v v value
  120.      * @param w w value
  121.      * @param gamma γ value
  122.      * @return value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup>(γ)
  123.      * @deprecated as of 10.2, replace by {@link #getValue(int, int, int, FieldDerivativeStructure)}
  124.      */
  125.     @Deprecated
  126.     public static <T extends RealFieldElement<T>> FieldDerivativeStructure<T> getValue(final int l, final int v, final int w,
  127.                                                                                        final FieldDerivativeStructure<T> gamma) {

  128.         final List<PolynomialFunction> polyList;
  129.         synchronized (MAP) {

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

  131.             // Check the existence of the corresponding key in the map.
  132.             if (!MAP.containsKey(key)) {
  133.                 MAP.put(key, new ArrayList<PolynomialFunction>());
  134.             }

  135.             polyList = MAP.get(key);

  136.         }

  137.         final PolynomialFunction polynomial;
  138.         synchronized (polyList) {
  139.             // If the l-th degree polynomial has not been computed yet, the polynomials
  140.             // up to this degree are computed.
  141.             for (int degree = polyList.size(); degree <= l; degree++) {
  142.                 polyList.add(degree, PolynomialsUtils.createJacobiPolynomial(degree, v, w));
  143.             }
  144.             polynomial = polyList.get(l);
  145.         }

  146.         // compute value and derivative
  147.         return polynomial.value(gamma);

  148.     }

  149.     /** Returns the value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup> evaluated at γ.
  150.      * <p>
  151.      * This method is guaranteed to be thread-safe
  152.      * </p>
  153.      * @param <T> the type of the field elements
  154.      * @param l degree of the polynomial
  155.      * @param v v value
  156.      * @param w w value
  157.      * @param gamma γ value
  158.      * @return value and derivatives of the Jacobi polynomial P<sub>l</sub><sup>v,w</sup>(γ)
  159.      * @since 10.2
  160.      */
  161.     public static <T extends RealFieldElement<T>> FieldGradient<T> getValue(final int l, final int v, final int w,
  162.                                                                             final FieldGradient<T> gamma) {

  163.         final List<PolynomialFunction> polyList;
  164.         synchronized (MAP) {

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

  166.             // Check the existence of the corresponding key in the map.
  167.             if (!MAP.containsKey(key)) {
  168.                 MAP.put(key, new ArrayList<PolynomialFunction>());
  169.             }

  170.             polyList = MAP.get(key);

  171.         }

  172.         final PolynomialFunction polynomial;
  173.         synchronized (polyList) {
  174.             // If the l-th degree polynomial has not been computed yet, the polynomials
  175.             // up to this degree are computed.
  176.             for (int degree = polyList.size(); degree <= l; degree++) {
  177.                 polyList.add(degree, PolynomialsUtils.createJacobiPolynomial(degree, v, w));
  178.             }
  179.             polynomial = polyList.get(l);
  180.         }

  181.         // compute value and derivative
  182.         return polynomial.value(gamma);

  183.     }

  184.     /** Inner class for Jacobi polynomials keys.
  185.      * <p>
  186.      * Please note that this class is not original content but is a copy from the
  187.      * Hipparchus library. This library is published under the
  188.      * Apache License, version 2.0.
  189.      * </p>
  190.      *
  191.      * @see org.hipparchus.analysis.polynomials.PolynomialsUtils
  192.      */
  193.     private static class JacobiKey {

  194.         /** First exponent. */
  195.         private final int v;

  196.         /** Second exponent. */
  197.         private final int w;

  198.         /** Simple constructor.
  199.          * @param v first exponent
  200.          * @param w second exponent
  201.          */
  202.         JacobiKey(final int v, final int w) {
  203.             this.v = v;
  204.             this.w = w;
  205.         }

  206.         /** Get hash code.
  207.          * @return hash code
  208.          */
  209.         @Override
  210.         public int hashCode() {
  211.             return (v << 16) ^ w;
  212.         }

  213.         /** Check if the instance represent the same key as another instance.
  214.          * @param key other key
  215.          * @return true if the instance and the other key refer to the same polynomial
  216.          */
  217.         @Override
  218.         public boolean equals(final Object key) {

  219.             if ((key == null) || !(key instanceof JacobiKey)) {
  220.                 return false;
  221.             }

  222.             final JacobiKey otherK = (JacobiKey) key;
  223.             return (v == otherK.v) && (w == otherK.w);

  224.         }
  225.     }

  226. }