FieldHansenZonalLinear.java

  1. /* Copyright 2002-2024 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.hansen;

  18. import org.hipparchus.Field;
  19. import org.hipparchus.CalculusFieldElement;
  20. import org.hipparchus.analysis.polynomials.PolynomialFunction;
  21. import org.hipparchus.util.FastMath;
  22. import org.hipparchus.util.MathArrays;

  23. /**
  24.  * Hansen coefficients K(t,n,s) for t=0 and n < 0.
  25.  * <p>
  26.  *Implements Collins 4-242 or echivalently, Danielson 2.7.3-(6) for Hansen Coefficients and
  27.  * Collins 4-245 or Danielson 3.1-(7) for derivatives. The recursions are transformed into
  28.  * composition of linear transformations to obtain the associated polynomials
  29.  * for coefficients and their derivatives - see Petre's paper
  30.  *
  31.  * @author Petre Bazavan
  32.  * @author Lucian Barbulescu
  33.  * @author Bryan Cazabonne
  34.  * @param <T> type of the field elements
  35.  */
  36. public class FieldHansenZonalLinear <T extends CalculusFieldElement<T>> {

  37.     /** The number of coefficients that will be computed with a set of roots. */
  38.     private static final int SLICE = 10;

  39.     /**
  40.      * The first vector of polynomials associated to Hansen coefficients and
  41.      * derivatives.
  42.      */
  43.     private final PolynomialFunction[][] mpvec;

  44.     /** The second vector of polynomials associated only to derivatives. */
  45.     private final PolynomialFunction[][] mpvecDeriv;

  46.     /** The Hansen coefficients used as roots. */
  47.     private final T[][] hansenRoot;

  48.     /** The derivatives of the Hansen coefficients used as roots. */
  49.     private final T[][] hansenDerivRoot;

  50.     /** The s coefficient. */
  51.     private final int s;

  52.     /**
  53.      * The offset used to identify the polynomial that corresponds to a negative
  54.      * value of n in the internal array that starts at 0.
  55.      */
  56.     private final int offset;

  57.     /** The number of slices needed to compute the coefficients. */
  58.     private final int numSlices;

  59.     /** 2<sup>s</sup>. */
  60.     private final double twots;

  61.     /** 2*s+1. */
  62.     private final int twosp1;

  63.     /** 2*s. */
  64.     private final int twos;

  65.     /** (2*s+1) / 2<sup>s</sup>. */
  66.     private final double twosp1otwots;

  67.     /**
  68.      * Constructor.
  69.      *
  70.      * @param nMax the maximum (absolute) value of n coefficient
  71.      * @param s s coefficient
  72.      * @param field field used by default
  73.      */
  74.     public FieldHansenZonalLinear(final int nMax, final int s, final Field<T> field) {
  75.         //Initialize fields
  76.         final int Nmin = -nMax - 1;
  77.         final int N0 = -(s + 2);
  78.         this.offset = nMax + 1;
  79.         this.s = s;
  80.         this.twots = FastMath.pow(2., s);
  81.         this.twos = 2 * s;
  82.         this.twosp1 = this.twos + 1;
  83.         this.twosp1otwots = (double) this.twosp1 / this.twots;

  84.         // prepare structures for stored data
  85.         final int size = nMax - s - 1;
  86.         mpvec      = new PolynomialFunction[size][];
  87.         mpvecDeriv = new PolynomialFunction[size][];

  88.         this.numSlices  = FastMath.max((int) FastMath.ceil(((double) size) / SLICE), 1);
  89.         hansenRoot      = MathArrays.buildArray(field, numSlices, 2);
  90.         hansenDerivRoot = MathArrays.buildArray(field, numSlices, 2);

  91.         // Prepare the data base of associated polynomials
  92.         HansenUtilities.generateZonalPolynomials(N0, Nmin, offset, SLICE, s,
  93.                                                  mpvec, mpvecDeriv);

  94.     }

  95.     /**
  96.      * Compute the roots for the Hansen coefficients and their derivatives.
  97.      *
  98.      * @param chi 1 / sqrt(1 - e²)
  99.      */
  100.     public void computeInitValues(final T chi) {
  101.         final Field<T> field = chi.getField();
  102.         final T zero = field.getZero();
  103.         // compute the values for n=s and n=s+1
  104.         // See Danielson 2.7.3-(6a,b)
  105.         hansenRoot[0][0] = zero;
  106.         hansenRoot[0][1] = FastMath.pow(chi, this.twosp1).divide(this.twots);
  107.         hansenDerivRoot[0][0] = zero;
  108.         hansenDerivRoot[0][1] = FastMath.pow(chi, this.twos).multiply(this.twosp1otwots);

  109.         final int st = -s - 1;
  110.         for (int i = 1; i < numSlices; i++) {
  111.             for (int j = 0; j < 2; j++) {
  112.                 // Get the required polynomials
  113.                 final PolynomialFunction[] mv = mpvec[st - (i * SLICE) - j + offset];
  114.                 final PolynomialFunction[] sv = mpvecDeriv[st - (i * SLICE) - j + offset];

  115.                 //Compute the root derivatives
  116.                 hansenDerivRoot[i][j] = mv[1].value(chi).multiply(hansenDerivRoot[i - 1][1]).
  117.                                         add(mv[0].value(chi).multiply(hansenDerivRoot[i - 1][0])).
  118.                                         add((sv[1].value(chi).multiply(hansenRoot[i - 1][1]).
  119.                                         add(sv[0].value(chi).multiply(hansenRoot[i - 1][0]))
  120.                                         ).divide(chi));
  121.                 hansenRoot[i][j] =     mv[1].value(chi).multiply(hansenRoot[i - 1][1]).
  122.                                        add(mv[0].value(chi).multiply(hansenRoot[i - 1][0]));

  123.             }

  124.         }
  125.     }

  126.     /**
  127.      * Get the K₀<sup>-n-1,s</sup> coefficient value.
  128.      *
  129.      * <p> The s value is given in the class constructor
  130.      *
  131.      * @param mnm1 (-n-1) coefficient
  132.      * @param chi The value of χ
  133.      * @return K₀<sup>-n-1,s</sup>
  134.      */
  135.     public T getValue(final int mnm1, final T chi) {
  136.         //Compute n
  137.         final int n = -mnm1 - 1;

  138.         //Compute the potential slice
  139.         int sliceNo = (n - s) / SLICE;
  140.         if (sliceNo < numSlices) {
  141.             //Compute the index within the slice
  142.             final int indexInSlice = (n - s) % SLICE;

  143.             //Check if a root must be returned
  144.             if (indexInSlice <= 1) {
  145.                 return hansenRoot[sliceNo][indexInSlice];
  146.             }
  147.         } else {
  148.             //the value was a potential root for a slice, but that slice was not required
  149.             //Decrease the slice number
  150.             sliceNo--;
  151.         }

  152.         // Danielson 2.7.3-(6c)/Collins 4-242 and Petre's paper
  153.         final PolynomialFunction[] v = mpvec[mnm1 + offset];
  154.         T ret = v[1].value(chi).multiply(hansenRoot[sliceNo][1]);
  155.         if (hansenRoot[sliceNo][0].getReal() != 0) {
  156.             ret = ret.add(v[0].value(chi).multiply(hansenRoot[sliceNo][0]));
  157.         }
  158.         return  ret;
  159.     }

  160.     /**
  161.      * Get the dK₀<sup>-n-1,s</sup> / d&Chi; coefficient derivative.
  162.      *
  163.      * <p> The s value is given in the class constructor.
  164.      *
  165.      * @param mnm1 (-n-1) coefficient
  166.      * @param chi The value of χ
  167.      * @return dK₀<sup>-n-1,s</sup> / d&Chi;
  168.      */
  169.     public T getDerivative(final int mnm1, final T chi) {
  170.         //Compute n
  171.         final int n = -mnm1 - 1;

  172.         //Compute the potential slice
  173.         int sliceNo = (n - s) / SLICE;
  174.         if (sliceNo < numSlices) {
  175.             //Compute the index within the slice
  176.             final int indexInSlice = (n - s) % SLICE;

  177.             //Check if a root must be returned
  178.             if (indexInSlice <= 1) {
  179.                 return hansenDerivRoot[sliceNo][indexInSlice];
  180.             }
  181.         } else {
  182.             //the value was a potential root for a slice, but that slice was not required
  183.             //Decrease the slice number
  184.             sliceNo--;
  185.         }

  186.         // Danielson 3.1-(7c) and Petre's paper
  187.         final PolynomialFunction[] v = mpvec[mnm1 + offset];
  188.         T ret = v[1].value(chi).multiply(hansenDerivRoot[sliceNo][1]);
  189.         if (hansenDerivRoot[sliceNo][0].getReal() != 0) {
  190.             ret = ret.add(v[0].value(chi).multiply(hansenDerivRoot[sliceNo][0]));
  191.         }

  192.         // Danielson 2.7.3-(6b)
  193.         final PolynomialFunction[] v1 = mpvecDeriv[mnm1 + offset];
  194.         T hret = v1[1].value(chi).multiply(hansenRoot[sliceNo][1]);
  195.         if (hansenRoot[sliceNo][0].getReal() != 0) {
  196.             hret = hret.add(v1[0].value(chi).multiply(hansenRoot[sliceNo][0]));
  197.         }
  198.         ret = ret.add(hret.divide(chi));

  199.         return ret;

  200.     }

  201. }