1   /* Copyright 2002-2021 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  
19  import org.hipparchus.Field;
20  import org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.util.FastMath;
22  
23  /** Compute the G<sub>ms</sub><sup>j</sup> and the H<sub>ms</sub><sup>j</sup>
24   *  polynomials in the equinoctial elements h, k and the direction cosines α and β
25   *  and their partial derivatives with respect to k, h, α and β.
26   *  <p>
27   *  The expressions used are equations 2.7.5-(1)(2) from the Danielson paper.
28   *  </p>
29   *  @author Romain Di Costanzo
30   *  @author Bryan Cazabonne (field translation)
31   */
32  public class FieldGHmsjPolynomials <T extends CalculusFieldElement<T>> {
33      /** C<sub>j</sub>(k, h), S<sub>j</sub>(k, h) coefficient.
34       * (k, h) are the (x, y) component of the eccentricity vector in equinoctial elements
35       */
36      private final FieldCjSjCoefficient<T> cjsjKH;
37  
38      /** C<sub>j</sub>(α, β), S<sub>j</sub>(α, β) coefficient.
39       * (α, β) are the direction cosines
40       */
41      private final FieldCjSjCoefficient<T> cjsjAB;
42  
43      /** Is the orbit represented as a retrograde orbit.
44       *  I = -1 if yes, +1 otherwise.
45       */
46      private int                   I;
47  
48      /** Zero for initialization. */
49      private final T zero;
50  
51      /** Create a set of G<sub>ms</sub><sup>j</sup> and H<sub>ms</sub><sup>j</sup> polynomials.
52       *  @param k X component of the eccentricity vector
53       *  @param h Y component of the eccentricity vector
54       *  @param alpha direction cosine α
55       *  @param beta direction cosine β
56       *  @param retroFactor -1 if the orbit is represented as retrograde, +1 otherwise
57       *  @param field field element
58       **/
59      public FieldGHmsjPolynomials(final T k, final T h,
60                              final T alpha, final T beta,
61                              final int retroFactor,
62                              final Field<T> field) {
63          zero = field.getZero();
64          this.cjsjKH = new FieldCjSjCoefficient<>(k, h, field);
65          this.cjsjAB = new FieldCjSjCoefficient<>(alpha, beta, field);
66          this.I = retroFactor;
67      }
68  
69      /** Get the G<sub>ms</sub><sup>j</sup> coefficient.
70       * @param m m subscript
71       * @param s s subscript
72       * @param j order
73       * @return the G<sub>ms</sub><sup>j</sup>
74       */
75      public T getGmsj(final int m, final int s, final int j) {
76          final int sMj = FastMath.abs(s - j);
77          T gms = zero;
78          if (FastMath.abs(s) <= m) {
79              final int mMis = m - I * s;
80              gms = cjsjKH.getCj(sMj).multiply(cjsjAB.getCj(mMis)).
81                    subtract(cjsjKH.getSj(sMj).multiply(cjsjAB.getSj(mMis)).multiply(sgn(s - j)).multiply(I));
82          } else {
83              final int sMim = FastMath.abs(s - I * m);
84              gms = cjsjKH.getCj(sMj).multiply(cjsjAB.getCj(sMim)).
85                    add(cjsjKH.getSj(sMj).multiply(cjsjAB.getSj(sMim)).multiply(sgn(s - j)).multiply(sgn(s - m)));
86          }
87          return gms;
88      }
89  
90      /** Get the H<sub>ms</sub><sup>j</sup> coefficient.
91       * @param m m subscript
92       * @param s s subscript
93       * @param j order
94       * @return the H<sub>ms</sub><sup>j</sup>
95       */
96      public T getHmsj(final int m, final int s, final int j) {
97          final int sMj = FastMath.abs(s - j);
98          T hms = zero;
99          if (FastMath.abs(s) <= m) {
100             final int mMis = m - I * s;
101             hms = cjsjKH.getCj(sMj).multiply(cjsjAB.getSj(mMis)).multiply(I).
102                             add(cjsjKH.getSj(sMj).multiply(cjsjAB.getCj(mMis)).multiply(sgn(s - j)));
103         } else {
104             final int sMim = FastMath.abs(s - I * m);
105             hms = cjsjKH.getCj(sMj).multiply(cjsjAB.getSj(sMim)).multiply(-sgn(s - m)).
106                   add(cjsjKH.getSj(sMj).multiply(cjsjAB.getCj(sMim)).multiply(sgn(s - j)));
107         }
108         return hms;
109     }
110 
111     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>k</sub> coefficient.
112      * @param m m subscript
113      * @param s s subscript
114      * @param j order
115      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>k</sub>
116      */
117     public T getdGmsdk(final int m, final int s, final int j) {
118         final int sMj = FastMath.abs(s - j);
119         T dGmsdk = zero;
120         if (FastMath.abs(s) <= m) {
121             final int mMis = m - I * s;
122             dGmsdk = cjsjKH.getDcjDk(sMj).multiply(cjsjAB.getCj(mMis)).
123                      subtract(cjsjKH.getDsjDk(sMj).multiply(cjsjAB.getSj(mMis)).multiply(I).multiply(sgn(s - j)));
124         } else {
125             final int sMim = FastMath.abs(s - I * m);
126             dGmsdk = cjsjKH.getDcjDk(sMj).multiply(cjsjAB.getCj(sMim)).
127                      add(cjsjKH.getDsjDk(sMj).multiply(cjsjAB.getSj(sMim)).multiply(sgn(s - m)).multiply(sgn(s - j)));
128         }
129         return dGmsdk;
130     }
131 
132     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>h</sub> coefficient.
133      * @param m m subscript
134      * @param s s subscript
135      * @param j order
136      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>h</sub>
137      */
138     public T getdGmsdh(final int m, final int s, final int j) {
139         final int sMj = FastMath.abs(s - j);
140         T dGmsdh = zero;
141         if (FastMath.abs(s) <= m) {
142             final int mMis = m - I * s;
143             dGmsdh = cjsjKH.getDcjDh(sMj).multiply(cjsjAB.getCj(mMis)).
144                      subtract(cjsjKH.getDsjDh(sMj).multiply(cjsjAB.getSj(mMis)).multiply(I).multiply(sgn(s - j)));
145         } else {
146             final int sMim = FastMath.abs(s - I * m);
147             dGmsdh = cjsjKH.getDcjDh(sMj).multiply(cjsjAB.getCj(sMim)).
148                      add(cjsjKH.getDsjDh(sMj).multiply(cjsjAB.getSj(sMim)).multiply(sgn(s - m)).multiply(sgn(s - j)));
149         }
150         return dGmsdh;
151     }
152 
153     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>α</sub> coefficient.
154      * @param m m subscript
155      * @param s s subscript
156      * @param j order
157      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>α</sub>
158      */
159     public T getdGmsdAlpha(final int m, final int s, final int j) {
160         final int sMj  = FastMath.abs(s - j);
161         T dGmsdAl = zero;
162         if (FastMath.abs(s) <= m) {
163             final int mMis = m - I * s;
164             dGmsdAl = cjsjKH.getCj(sMj).multiply(cjsjAB.getDcjDk(mMis)).
165                       subtract(cjsjKH.getSj(sMj).multiply(cjsjAB.getDsjDk(mMis)).multiply(I).multiply(sgn(s - j)));
166         } else {
167             final int sMim = FastMath.abs(s - I * m);
168             dGmsdAl = cjsjKH.getCj(sMj).multiply(cjsjAB.getDcjDk(sMim)).
169                       add(cjsjKH.getSj(sMj).multiply(cjsjAB.getDsjDk(sMim)).multiply(sgn(s - j)).multiply(sgn(s - m)));
170         }
171         return dGmsdAl;
172     }
173 
174     /** Get the dG<sub>ms</sub><sup>j</sup> / d<sub>β</sub> coefficient.
175      * @param m m subscript
176      * @param s s subscript
177      * @param j order
178      * @return dG<sub>ms</sub><sup>j</sup> / d<sub>β</sub>
179      */
180     public T getdGmsdBeta(final int m, final int s, final int j) {
181         final int sMj = FastMath.abs(s - j);
182         T dGmsdBe = zero;
183         if (FastMath.abs(s) <= m) {
184             final int mMis = m - I * s;
185             dGmsdBe = cjsjKH.getCj(sMj).multiply(cjsjAB.getDcjDh(mMis)).
186                       subtract(cjsjKH.getSj(sMj).multiply(cjsjAB.getDsjDh(mMis)).multiply(I).multiply(sgn(s - j)));
187         } else {
188             final int sMim = FastMath.abs(s - I * m);
189             dGmsdBe = cjsjKH.getCj(sMj).multiply(cjsjAB.getDcjDh(sMim)).
190                       add(cjsjKH.getSj(sMj).multiply(cjsjAB.getDsjDh(sMim)).multiply(sgn(s - j)).multiply(sgn(s - m)));
191         }
192         return dGmsdBe;
193     }
194 
195     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>k</sub> coefficient.
196      * @param m m subscript
197      * @param s s subscript
198      * @param j order
199      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>k</sub>
200      */
201     public T getdHmsdk(final int m, final int s, final int j) {
202         final int sMj = FastMath.abs(s - j);
203         T dHmsdk = zero;
204         if (FastMath.abs(s) <= m) {
205             final int mMis = m - I * s;
206             dHmsdk = cjsjKH.getDcjDk(sMj).multiply(cjsjAB.getSj(mMis)).multiply(I).
207                      add(cjsjKH.getDsjDk(sMj).multiply(cjsjAB.getCj(mMis)).multiply(sgn(s - j)));
208         } else {
209             final int sMim = FastMath.abs(s - I * m);
210             dHmsdk = cjsjKH.getDcjDk(sMj).multiply(cjsjAB.getSj(sMim)).multiply(-sgn(s - m)).
211                      add(cjsjKH.getDsjDk(sMj).multiply(cjsjAB.getCj(sMim)).multiply(sgn(s - j)));
212         }
213         return dHmsdk;
214     }
215 
216     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>h</sub> coefficient.
217      * @param m m subscript
218      * @param s s subscript
219      * @param j order
220      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>h</sub>
221      */
222     public T getdHmsdh(final int m,  final int s, final int j) {
223         final int sMj = FastMath.abs(s - j);
224         T dHmsdh = zero;
225         if (FastMath.abs(s) <= m) {
226             final int mMis = m - I * s;
227             dHmsdh = cjsjKH.getDcjDh(sMj).multiply(cjsjAB.getSj(mMis)).multiply(I).
228                      add(cjsjKH.getDsjDh(sMj).multiply(cjsjAB.getCj(mMis)).multiply(sgn(s - j)));
229         } else {
230             final int sMim = FastMath.abs(s - I * m);
231             dHmsdh = cjsjKH.getDcjDh(sMj).multiply(cjsjAB.getSj(sMim)).multiply(-sgn(s - m)).
232                      add(cjsjKH.getDsjDh(sMj).multiply(cjsjAB.getCj(sMim)).multiply(sgn(s - j)));
233         }
234         return dHmsdh;
235     }
236 
237     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>α</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>α</sub>
242      */
243     public T getdHmsdAlpha(final int m, final int s, final int j) {
244         final int sMj  = FastMath.abs(s - j);
245         T dHmsdAl = zero;
246         if (FastMath.abs(s) <= m) {
247             final int mMis = m - I * s;
248             dHmsdAl = cjsjKH.getCj(sMj).multiply(cjsjAB.getDsjDk(mMis)).multiply(I).
249                       add(cjsjKH.getSj(sMj).multiply(cjsjAB.getDcjDk(mMis)).multiply(sgn(s - j)));
250         } else {
251             final int sMim = FastMath.abs(s - I * m);
252             dHmsdAl = cjsjKH.getCj(sMj).multiply(cjsjAB.getDsjDk(sMim)).multiply(-sgn(s - m)).
253                       add(cjsjKH.getSj(sMj).multiply(cjsjAB.getDcjDk(sMim)).multiply(sgn(s - j)));
254         }
255         return dHmsdAl;
256     }
257 
258     /** Get the dH<sub>ms</sub><sup>j</sup> / d<sub>β</sub> coefficient.
259      * @param m m subscript
260      * @param s s subscript
261      * @param j order
262      * @return dH<sub>ms</sub><sup>j</sup> / d<sub>β</sub>
263      */
264     public T getdHmsdBeta(final int m, final int s, final int j) {
265         final int sMj = FastMath.abs(s - j);
266         T dHmsdBe = zero;
267         if (FastMath.abs(s) <= m) {
268             final int mMis = m - I * s;
269             dHmsdBe = cjsjKH.getCj(sMj).multiply(cjsjAB.getDsjDh(mMis)).multiply(I).
270                       add(cjsjKH.getSj(sMj).multiply(cjsjAB.getDcjDh(mMis)).multiply(sgn(s - j)));
271         } else {
272             final int sMim = FastMath.abs(s - I * m);
273             dHmsdBe = cjsjKH.getCj(sMj).multiply(cjsjAB.getDsjDh(sMim)).multiply(-sgn(s - m)).
274                       add(cjsjKH.getSj(sMj).multiply(cjsjAB.getDcjDh(sMim)).multiply(sgn(s - j)));
275         }
276         return dHmsdBe;
277     }
278 
279     /** Get the sign of an integer.
280      *  @param i number on which evaluation is done
281      *  @return -1 or +1 depending on sign of i
282      */
283     private int sgn(final int i) {
284         return (i < 0) ? -1 : 1;
285     }
286 }