1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.data;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.hipparchus.RealFieldElement;
23 import org.hipparchus.util.MathArrays;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public class PoissonSeries {
40
41
42 private final PolynomialNutation polynomial;
43
44
45 private final Map<Long, SeriesTerm> series;
46
47
48
49
50
51 public PoissonSeries(final PolynomialNutation polynomial, final Map<Long, SeriesTerm> series) {
52 this.polynomial = polynomial;
53 this.series = series;
54 }
55
56
57
58
59 public PolynomialNutation getPolynomial() {
60 return polynomial;
61 }
62
63
64
65
66 public int getNonPolynomialSize() {
67 return series.size();
68 }
69
70
71
72
73
74 public double value(final BodiesElements elements) {
75
76
77 final double p = polynomial.value(elements.getTC());
78
79
80
81
82
83 double npHigh = 0;
84 double npLow = 0;
85 for (final Map.Entry<Long, SeriesTerm> entry : series.entrySet()) {
86 final double v = entry.getValue().value(elements)[0];
87 final double sum = npHigh + v;
88 final double sPrime = sum - v;
89 final double tPrime = sum - sPrime;
90 final double deltaS = npHigh - sPrime;
91 final double deltaT = v - tPrime;
92 npLow += deltaS + deltaT;
93 npHigh = sum;
94 }
95
96
97 return p + (npHigh + npLow);
98
99 }
100
101
102
103
104
105
106 public <T extends RealFieldElement<T>> T value(final FieldBodiesElements<T> elements) {
107
108
109 final T tc = elements.getTC();
110 final T p = polynomial.value(tc);
111
112
113 T sum = tc.getField().getZero();
114 for (final Map.Entry<Long, SeriesTerm> entry : series.entrySet()) {
115 sum = sum.add(entry.getValue().value(elements)[0]);
116 }
117
118
119 return p.add(sum);
120
121 }
122
123
124
125
126
127 public interface CompiledSeries {
128
129
130
131
132
133 double[] value(BodiesElements elements);
134
135
136
137
138
139 double[] derivative(BodiesElements elements);
140
141
142
143
144
145
146 <S extends RealFieldElement<S>> S[] value(FieldBodiesElements<S> elements);
147
148
149
150
151
152
153 <S extends RealFieldElement<S>> S[] derivative(FieldBodiesElements<S> elements);
154
155 }
156
157
158
159
160
161
162 @SafeVarargs
163 public static CompiledSeries compile(final PoissonSeries... poissonSeries) {
164
165
166 final PolynomialNutationNutation">PolynomialNutation[] polynomials = new PolynomialNutation[poissonSeries.length];
167 for (int i = 0; i < polynomials.length; ++i) {
168 polynomials[i] = poissonSeries[i].polynomial;
169 }
170
171
172 final Map<Long, SeriesTerm> joinedMap = new HashMap<Long, SeriesTerm>();
173 for (final PoissonSeries ps : poissonSeries) {
174 for (Map.Entry<Long, SeriesTerm> entry : ps.series.entrySet()) {
175 final long key = entry.getKey();
176 if (!joinedMap.containsKey(key)) {
177
178
179 final int[] m = NutationCodec.decode(key);
180
181
182 final SeriesTerm term =
183 SeriesTerm.buildTerm(m[0],
184 m[1], m[2], m[3], m[4], m[5],
185 m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14]);
186 term.add(poissonSeries.length - 1, -1, Double.NaN, Double.NaN);
187
188
189 joinedMap.put(key, term);
190
191 }
192 }
193 }
194
195
196
197 for (int i = 0; i < poissonSeries.length; ++i) {
198 for (final Map.Entry<Long, SeriesTerm> entry : poissonSeries[i].series.entrySet()) {
199 final SeriesTerm singleTerm = entry.getValue();
200 final SeriesTerm joinedTerm = joinedMap.get(entry.getKey());
201 for (int degree = 0; degree <= singleTerm.getDegree(0); ++degree) {
202 joinedTerm.add(i, degree,
203 singleTerm.getSinCoeff(0, degree),
204 singleTerm.getCosCoeff(0, degree));
205 }
206 }
207 }
208
209
210 final SeriesTerm">SeriesTerm[] joinedTerms = new SeriesTerm[joinedMap.size()];
211 int index = 0;
212 for (final Map.Entry<Long, SeriesTerm> entry : joinedMap.entrySet()) {
213 joinedTerms[index++] = entry.getValue();
214 }
215
216 return new CompiledSeries() {
217
218
219 @Override
220 public double[] value(final BodiesElements elements) {
221
222
223
224
225
226 final double[] npHigh = new double[polynomials.length];
227 final double[] npLow = new double[polynomials.length];
228 for (final SeriesTerm term : joinedTerms) {
229 final double[] termValue = term.value(elements);
230 for (int i = 0; i < termValue.length; ++i) {
231 final double v = termValue[i];
232 final double sum = npHigh[i] + v;
233 final double sPrime = sum - v;
234 final double tPrime = sum - sPrime;
235 final double deltaS = npHigh[i] - sPrime;
236 final double deltaT = v - tPrime;
237 npLow[i] += deltaS + deltaT;
238 npHigh[i] = sum;
239 }
240 }
241
242
243 for (int i = 0; i < npHigh.length; ++i) {
244 npHigh[i] += npLow[i] + polynomials[i].value(elements.getTC());
245 }
246 return npHigh;
247
248 }
249
250
251 @Override
252 public double[] derivative(final BodiesElements elements) {
253
254
255 final double[] v = new double[polynomials.length];
256 for (final SeriesTerm term : joinedTerms) {
257 final double[] termDerivative = term.derivative(elements);
258 for (int i = 0; i < termDerivative.length; ++i) {
259 v[i] += termDerivative[i];
260 }
261 }
262
263
264 for (int i = 0; i < v.length; ++i) {
265 v[i] += polynomials[i].derivative(elements.getTC());
266 }
267 return v;
268
269 }
270
271
272 @Override
273 public <S extends RealFieldElement<S>> S[] value(final FieldBodiesElements<S> elements) {
274
275
276 final S[] v = MathArrays.buildArray(elements.getTC().getField(), polynomials.length);
277 for (final SeriesTerm term : joinedTerms) {
278 final S[] termValue = term.value(elements);
279 for (int i = 0; i < termValue.length; ++i) {
280 v[i] = v[i].add(termValue[i]);
281 }
282 }
283
284
285 final S tc = elements.getTC();
286 for (int i = 0; i < v.length; ++i) {
287 v[i] = v[i].add(polynomials[i].value(tc));
288 }
289 return v;
290
291 }
292
293
294 @Override
295 public <S extends RealFieldElement<S>> S[] derivative(final FieldBodiesElements<S> elements) {
296
297
298 final S[] v = MathArrays.buildArray(elements.getTC().getField(), polynomials.length);
299 for (final SeriesTerm term : joinedTerms) {
300 final S[] termDerivative = term.derivative(elements);
301 for (int i = 0; i < termDerivative.length; ++i) {
302 v[i] = v[i].add(termDerivative[i]);
303 }
304 }
305
306
307 final S tc = elements.getTC();
308 for (int i = 0; i < v.length; ++i) {
309 v[i] = v[i].add(polynomials[i].derivative(tc));
310 }
311 return v;
312
313 }
314
315 };
316
317 }
318
319 }