GHmsjPolynomials.java

  1. /* Copyright 2002-2013 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.List;

  20. import org.apache.commons.math3.complex.Complex;
  21. import org.apache.commons.math3.util.FastMath;

  22. /** Compute the G<sub>ms</sub><sup>j</sup> and the H<sub>ms</sub><sup>j</sup>
  23.  *  polynomials in the equinoctial elements h, k and the direction cosines &alpha; and &beta;
  24.  *  and their partial derivatives with respect to k, h, &alpha; and &beta;.
  25.  *  <p>
  26.  *  The expressions used are equations 2.7.5-(1)(2) from the Danielson paper.
  27.  *  </p>
  28.  *  @author Romain Di Costanzo
  29.  */
  30. public class GHmsjPolynomials {

  31.     /** C<sub>j</sub>(k, h), S<sub>j</sub>(k, h) coefficient.
  32.      * (k, h) are the (x, y) component of the eccentricity vector in equinoctial elements
  33.      */
  34.     private final CjSjCoefficient cjsjKH;

  35.     /** C<sub>j</sub>(&alpha;, &beta;), S<sub>j</sub>(&alpha;, &beta;) coefficient.
  36.      * (&alpha;, &beta;) are the direction cosines
  37.      */
  38.     private final CjSjCoefficient cjsjAB;

  39.     /** Is the orbit represented as a retrograde orbit.
  40.      *  I = -1 if yes, +1 otherwise.
  41.      */
  42.     private int                   I;

  43.     /** Create a set of G<sub>ms</sub><sup>j</sup> and H<sub>ms</sub><sup>j</sup> polynomials.
  44.      *  @param k X component of the eccentricity vector
  45.      *  @param h Y component of the eccentricity vector
  46.      *  @param alpha direction cosine &alpha;
  47.      *  @param beta direction cosine &beta;
  48.      *  @param retroFactor -1 if the orbit is represented as retrograde, +1 otherwise
  49.      **/
  50.     public GHmsjPolynomials(final double k, final double h,
  51.                             final double alpha, final double beta,
  52.                             final int retroFactor) {
  53.         this.cjsjKH = new CjSjCoefficient(k, h);
  54.         this.cjsjAB = new CjSjCoefficient(alpha, beta);
  55.         this.I = retroFactor;
  56.     }

  57.     /** Get the G<sub>ms</sub><sup>j</sup> coefficient.
  58.      * @param m m subscript
  59.      * @param s s subscript
  60.      * @param j order
  61.      * @return the G<sub>ms</sub><sup>j</sup>
  62.      */
  63.     public double getGmsj(final int m, final int s, final int j) {
  64.         final int sMj = FastMath.abs(s - j);
  65.         double gms = 0d;
  66.         if (FastMath.abs(s) <= m) {
  67.             final int mMis = m - I * s;
  68.             gms = cjsjKH.getCj(sMj) * cjsjAB.getCj(mMis) -
  69.                   I * sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getSj(mMis);
  70.         } else {
  71.             final int sMim = FastMath.abs(s - I * m);
  72.             gms = cjsjKH.getCj(sMj) * cjsjAB.getCj(sMim) +
  73.                   sgn(s - j) * sgn(s - m) * cjsjKH.getSj(sMj) * cjsjAB.getSj(sMim);
  74.         }
  75.         return gms;
  76.     }

  77.     /** Get the H<sub>ms</sub><sup>j</sup> coefficient.
  78.      * @param m m subscript
  79.      * @param s s subscript
  80.      * @param j order
  81.      * @return the H<sub>ms</sub><sup>j</sup>
  82.      */
  83.     public double getHmsj(final int m, final int s, final int j) {
  84.         final int sMj = FastMath.abs(s - j);
  85.         double hms = 0d;
  86.         if (FastMath.abs(s) <= m) {
  87.             final int mMis = m - I * s;
  88.             hms = I * cjsjKH.getCj(sMj) * cjsjAB.getSj(mMis) + sgn(s - j) *
  89.                   cjsjKH.getSj(sMj) * cjsjAB.getCj(mMis);
  90.         } else {
  91.             final int sMim = FastMath.abs(s - I * m);
  92.             hms = -sgn(s - m) * cjsjKH.getCj(sMj) * cjsjAB.getSj(sMim) +
  93.                    sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getCj(sMim);
  94.         }
  95.         return hms;
  96.     }

  97.     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>k</sub> coefficient.
  98.      * @param m m subscript
  99.      * @param s s subscript
  100.      * @param j order
  101.      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>k</sub>
  102.      */
  103.     public double getdGmsdk(final int m, final int s, final int j) {
  104.         final int sMj = FastMath.abs(s - j);
  105.         double dGmsdk = 0d;
  106.         if (FastMath.abs(s) <= m) {
  107.             final int mMis = m - I * s;
  108.             dGmsdk = cjsjKH.getDcjDk(sMj) * cjsjAB.getCj(mMis) -
  109.                    I * sgn(s - j) * cjsjKH.getDsjDk(sMj) * cjsjAB.getSj(mMis);
  110.         } else {
  111.             final int sMim = FastMath.abs(s - I * m);
  112.             dGmsdk = cjsjKH.getDcjDk(sMj) * cjsjAB.getCj(sMim) +
  113.                     sgn(s - j) * sgn(s - m) * cjsjKH.getDsjDk(sMj) * cjsjAB.getSj(sMim);
  114.         }
  115.         return dGmsdk;
  116.     }

  117.     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>h</sub> coefficient.
  118.      * @param m m subscript
  119.      * @param s s subscript
  120.      * @param j order
  121.      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>h</sub>
  122.      */
  123.     public double getdGmsdh(final int m, final int s, final int j) {
  124.         final int sMj = FastMath.abs(s - j);
  125.         double dGmsdh = 0d;
  126.         if (FastMath.abs(s) <= m) {
  127.             final int mMis = m - I * s;
  128.             dGmsdh = cjsjKH.getDcjDh(sMj) * cjsjAB.getCj(mMis) -
  129.                     I * sgn(s - j) * cjsjKH.getDsjDh(sMj) * cjsjAB.getSj(mMis);
  130.         } else {
  131.             final int sMim = FastMath.abs(s - I * m);
  132.             dGmsdh = cjsjKH.getDcjDh(sMj) * cjsjAB.getCj(sMim) +
  133.                     sgn(s - j) * sgn(s - m) * cjsjKH.getDsjDh(sMj) * cjsjAB.getSj(sMim);
  134.         }
  135.         return dGmsdh;
  136.     }

  137.     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>&alpha;</sub> coefficient.
  138.      * @param m m subscript
  139.      * @param s s subscript
  140.      * @param j order
  141.      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>&alpha;</sub>
  142.      */
  143.     public double getdGmsdAlpha(final int m, final int s, final int j) {
  144.         final int sMj  = FastMath.abs(s - j);
  145.         double dGmsdAl = 0d;
  146.         if (FastMath.abs(s) <= m) {
  147.             final int mMis = m - I * s;
  148.             dGmsdAl = cjsjKH.getCj(sMj) * cjsjAB.getDcjDk(mMis) -
  149.                    I * sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getDsjDk(mMis);
  150.         } else {
  151.             final int sMim = FastMath.abs(s - I * m);
  152.             dGmsdAl = cjsjKH.getCj(sMj) * cjsjAB.getDcjDk(sMim) +
  153.                     sgn(s - j) * sgn(s - m) * cjsjKH.getSj(sMj) * cjsjAB.getDsjDk(sMim);
  154.         }
  155.         return dGmsdAl;
  156.     }

  157.     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>&beta;</sub> coefficient.
  158.      * @param m m subscript
  159.      * @param s s subscript
  160.      * @param j order
  161.      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>&beta;</sub>
  162.      */
  163.     public double getdGmsdBeta(final int m, final int s, final int j) {
  164.         final int sMj = FastMath.abs(s - j);
  165.         double dGmsdBe = 0d;
  166.         if (FastMath.abs(s) <= m) {
  167.             final int mMis = m - I * s;
  168.             dGmsdBe = cjsjKH.getCj(sMj) * cjsjAB.getDcjDh(mMis) -
  169.                     I * sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getDsjDh(mMis);
  170.         } else {
  171.             final int sMim = FastMath.abs(s - I * m);
  172.             dGmsdBe = cjsjKH.getCj(sMj) * cjsjAB.getDcjDh(sMim) +
  173.                     sgn(s - j) * sgn(s - m) * cjsjKH.getSj(sMj) * cjsjAB.getDsjDh(sMim);
  174.         }
  175.         return dGmsdBe;
  176.     }

  177.     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>k</sub> coefficient.
  178.      * @param m m subscript
  179.      * @param s s subscript
  180.      * @param j order
  181.      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>k</sub>
  182.      */
  183.     public double getdHmsdk(final int m, final int s, final int j) {
  184.         final int sMj = FastMath.abs(s - j);
  185.         double dHmsdk = 0d;
  186.         if (FastMath.abs(s) <= m) {
  187.             final int mMis = m - I * s;
  188.             dHmsdk = I * cjsjKH.getDcjDk(sMj) * cjsjAB.getSj(mMis) +
  189.                     sgn(s - j) * cjsjKH.getDsjDk(sMj) * cjsjAB.getCj(mMis);
  190.         } else {
  191.             final int sMim = FastMath.abs(s - I * m);
  192.             dHmsdk = -sgn(s - m) * cjsjKH.getDcjDk(sMj) * cjsjAB.getSj(sMim) +
  193.                     sgn(s - j) * cjsjKH.getDsjDk(sMj) * cjsjAB.getCj(sMim);
  194.         }
  195.         return dHmsdk;
  196.     }

  197.     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>h</sub> coefficient.
  198.      * @param m m subscript
  199.      * @param s s subscript
  200.      * @param j order
  201.      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>h</sub>
  202.      */
  203.     public double getdHmsdh(final int m,  final int s, final int j) {
  204.         final int sMj = FastMath.abs(s - j);
  205.         double dHmsdh = 0d;
  206.         if (FastMath.abs(s) <= m) {
  207.             final int mMis = m - I * s;
  208.             dHmsdh = I * cjsjKH.getDcjDh(sMj) * cjsjAB.getSj(mMis) +
  209.                     sgn(s - j) * cjsjKH.getDsjDh(sMj) * cjsjAB.getCj(mMis);
  210.         } else {
  211.             final int sMim = FastMath.abs(s - I * m);
  212.             dHmsdh = -sgn(s - m) * cjsjKH.getDcjDh(sMj) * cjsjAB.getSj(sMim) +
  213.                     sgn(s - j) * cjsjKH.getDsjDh(sMj) * cjsjAB.getCj(sMim);
  214.         }
  215.         return dHmsdh;
  216.     }

  217.     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>&alpha;</sub> coefficient.
  218.      * @param m m subscript
  219.      * @param s s subscript
  220.      * @param j order
  221.      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>&alpha;</sub>
  222.      */
  223.     public double getdHmsdAlpha(final int m, final int s, final int j) {
  224.         final int sMj  = FastMath.abs(s - j);
  225.         double dHmsdAl = 0d;
  226.         if (FastMath.abs(s) <= m) {
  227.             final int mMis = m - I * s;
  228.             dHmsdAl = I * cjsjKH.getCj(sMj) * cjsjAB.getDsjDk(mMis) +
  229.                     sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getDcjDk(mMis);
  230.         } else {
  231.             final int sMim = FastMath.abs(s - I * m);
  232.             dHmsdAl = -sgn(s - m) * cjsjKH.getCj(sMj) * cjsjAB.getDsjDk(sMim) +
  233.                     sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getDcjDk(sMim);
  234.         }
  235.         return dHmsdAl;
  236.     }

  237.     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>&beta;</sub> coefficient.
  238.      * @param m m subscript
  239.      * @param s s subscript
  240.      * @param j order
  241.      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>&beta;</sub>
  242.      */
  243.     public double getdHmsdBeta(final int m, final int s, final int j) {
  244.         final int sMj = FastMath.abs(s - j);
  245.         double dHmsdBe = 0d;
  246.         if (FastMath.abs(s) <= m) {
  247.             final int mMis = m - I * s;
  248.             dHmsdBe = I * cjsjKH.getCj(sMj) * cjsjAB.getDsjDh(mMis) +
  249.                    sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getDcjDh(mMis);
  250.         } else {
  251.             final int sMim = FastMath.abs(s - I * m);
  252.             dHmsdBe = -sgn(s - m) * cjsjKH.getCj(sMj) * cjsjAB.getDsjDh(sMim) +
  253.                     sgn(s - j) * cjsjKH.getSj(sMj) * cjsjAB.getDcjDh(sMim);
  254.         }
  255.         return dHmsdBe;
  256.     }

  257.     /** Get the sign of an integer.
  258.      *  @param i number on which evaluation is done
  259.      *  @return -1 or +1 depending on sign of i
  260.      */
  261.     private int sgn(final int i) {
  262.         return (i < 0) ? -1 : 1;
  263.     }

  264.     /** Compute the S<sub>j</sub>(k, h) and the C<sub>j</sub>(k, h) series
  265.      *  and their partial derivatives with respect to k and h.
  266.      *  <p>
  267.      *  Those series are given in Danielson paper by expression 2.5.3-(5):
  268.      *  <pre>C<sub>j</sub>(k, h) + i S<sub>j</sub>(k, h) = (k+ih)<sup>j</sup> </pre>
  269.      *  </p>
  270.      *  The C<sub>j</sub>(k, h) and the S<sub>j</sub>(k, h) elements are store as an
  271.      *  {@link ArrayList} of {@link Complex} number, the C<sub>j</sub>(k, h) being
  272.      *  represented by the real and the S<sub>j</sub>(k, h) by the imaginary part.
  273.      */
  274.     private static class CjSjCoefficient {

  275.         /** Last computed order j. */
  276.         private int jLast;

  277.         /** Complex base (k + ih) of the C<sub>j</sub>, S<sub>j</sub> series. */
  278.         private final Complex kih;

  279.         /** List of computed elements. */
  280.         private final List<Complex> cjsj;

  281.         /** C<sub>j</sub>(k, h) and S<sub>j</sub>(k, h) constructor.
  282.          * @param k k value
  283.          * @param h h value
  284.          */
  285.         public CjSjCoefficient(final double k, final double h) {
  286.             kih  = new Complex(k, h);
  287.             cjsj = new ArrayList<Complex>();
  288.             cjsj.add(new Complex(1, 0));
  289.             cjsj.add(kih);
  290.             jLast = 1;
  291.         }

  292.         /** Get the C<sub>j</sub> coefficient.
  293.          * @param j order
  294.          * @return C<sub>j</sub>
  295.          */
  296.         public double getCj(final int j) {
  297.             if (j > jLast) {
  298.                 // Update to order j
  299.                 updateCjSj(j);
  300.             }
  301.             return cjsj.get(j).getReal();
  302.         }

  303.         /** Get the S<sub>j</sub> coefficient.
  304.          * @param j order
  305.          * @return S<sub>j</sub>
  306.          */
  307.         public double getSj(final int j) {
  308.             if (j > jLast) {
  309.                 // Update to order j
  310.                 updateCjSj(j);
  311.             }
  312.             return cjsj.get(j).getImaginary();
  313.         }

  314.         /** Get the dC<sub>j</sub> / dk coefficient.
  315.          * @param j order
  316.          * @return dC<sub>j</sub> / d<sub>k</sub>
  317.          */
  318.         public double getDcjDk(final int j) {
  319.             return j == 0 ? 0 : j * getCj(j - 1);
  320.         }

  321.         /** Get the dS<sub>j</sub> / dk coefficient.
  322.          * @param j order
  323.          * @return dS<sub>j</sub> / d<sub>k</sub>
  324.          */
  325.         public double getDsjDk(final int j) {
  326.             return j == 0 ? 0 : j * getSj(j - 1);
  327.         }

  328.         /** Get the dC<sub>j</sub> / dh coefficient.
  329.          * @param j order
  330.          * @return dC<sub>i</sub> / d<sub>k</sub>
  331.          */
  332.         public double getDcjDh(final int j) {
  333.             return j == 0 ? 0 : -j * getSj(j - 1);
  334.         }

  335.         /** Get the dS<sub>j</sub> / dh coefficient.
  336.          * @param j order
  337.          * @return dS<sub>j</sub> / d<sub>h</sub>
  338.          */
  339.         public double getDsjDh(final int j) {
  340.             return j == 0 ? 0 : j * getCj(j - 1);
  341.         }

  342.         /** Update the cjsj up to order j.
  343.          * @param j order
  344.          */
  345.         private void updateCjSj(final int j) {
  346.             Complex last = cjsj.get(cjsj.size() - 1);
  347.             for (int i = jLast; i < j; i++) {
  348.                 final Complex next = last.multiply(kih);
  349.                 cjsj.add(next);
  350.                 last = next;
  351.             }
  352.             jLast = j;
  353.         }

  354.     }

  355. }