1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst.utilities;
18
19 import java.util.ArrayList;
20
21 import org.apache.commons.math3.analysis.interpolation.HermiteInterpolator;
22 import org.apache.commons.math3.util.FastMath;
23 import org.orekit.time.AbsoluteDate;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class ShortPeriodicsInterpolatedCoefficient {
38
39
40 private ArrayList<Double> values;
41
42
43 private ArrayList<AbsoluteDate> abscissae;
44
45
46 private int interpolationPoints;
47
48
49 private int latestClosestNeighbor;
50
51
52
53
54 public ShortPeriodicsInterpolatedCoefficient(final int interpolationPoints) {
55 this.interpolationPoints = interpolationPoints;
56 this.abscissae = new ArrayList<AbsoluteDate>();
57 this.values = new ArrayList<Double>();
58 this.latestClosestNeighbor = 0;
59 }
60
61
62
63
64
65 public double value(final AbsoluteDate date) {
66
67 final int[] neighbors = getNeighborsIndices(date);
68
69
70 final HermiteInterpolator interpolator = new HermiteInterpolator();
71 for (int i : neighbors) {
72 final double abscissa = abscissae.get(i).durationFrom(date);
73 final double value = values.get(i);
74
75 interpolator.addSamplePoint(abscissa, new double[]{value});
76 }
77
78
79 return interpolator.value(0.0)[0];
80 }
81
82
83
84
85
86 private int[] getNeighborsIndices(final AbsoluteDate date) {
87 final int sizeofNeighborhood = FastMath.min(interpolationPoints, abscissae.size());
88 final int[] neighborsIndices = new int[sizeofNeighborhood];
89
90
91
92
93 if (interpolationPoints >= abscissae.size()) {
94 for (int i = 0; i < sizeofNeighborhood; i++) {
95 neighborsIndices[i] = i;
96 }
97 }
98
99
100
101 else {
102 final int closestNeighbor = getClosestNeighbor(date);
103
104 neighborsIndices[0] = closestNeighbor;
105
106 int i = 1;
107 int lowerNeighbor = closestNeighbor - 1;
108 int upperNeighbor = closestNeighbor + 1;
109
110 while (i < interpolationPoints) {
111 if (lowerNeighbor < 0) {
112 neighborsIndices[i] = upperNeighbor;
113 upperNeighbor++;
114 }
115 else if (upperNeighbor >= abscissae.size()) {
116 neighborsIndices[i] = lowerNeighbor;
117 lowerNeighbor--;
118 }
119 else {
120 final double lowerNeighborDistance = FastMath.abs(abscissae.get(lowerNeighbor).durationFrom(date));
121 final double upperNeighborDistance = FastMath.abs(abscissae.get(upperNeighbor).durationFrom(date));
122
123 if (lowerNeighborDistance <= upperNeighborDistance) {
124 neighborsIndices[i] = lowerNeighbor;
125 lowerNeighbor--;
126 }
127 else {
128 neighborsIndices[i] = upperNeighbor;
129 upperNeighbor++;
130 }
131 }
132
133 i++;
134 }
135 }
136
137 return neighborsIndices;
138 }
139
140
141
142
143
144 private int getClosestNeighbor(final AbsoluteDate date) {
145
146
147
148
149
150 int closestNeighbor = latestClosestNeighbor;
151
152
153 if (date.compareTo(abscissae.get(0)) <= 0) {
154 closestNeighbor = 0;
155 }
156
157 else if (date.compareTo(abscissae.get(abscissae.size() - 1)) >= 0) {
158 closestNeighbor = abscissae.size() - 1;
159 }
160
161
162 else {
163 int lowerBorder = latestClosestNeighbor;
164 int upperBorder = latestClosestNeighbor;
165
166 final int searchDirection = date.compareTo(abscissae.get(latestClosestNeighbor));
167 if (searchDirection > 0) {
168 upperBorder++;
169 while (date.compareTo(abscissae.get(upperBorder)) > 0) {
170 upperBorder++;
171 lowerBorder++;
172 }
173 }
174 else {
175 lowerBorder--;
176 while (date.compareTo(abscissae.get(lowerBorder)) < 0) {
177 upperBorder--;
178 lowerBorder--;
179 }
180 }
181
182 final double lowerDistance = FastMath.abs(date.durationFrom(abscissae.get(lowerBorder)));
183 final double upperDistance = FastMath.abs(date.durationFrom(abscissae.get(upperBorder)));
184
185 closestNeighbor = (lowerDistance < upperDistance) ? lowerBorder : upperBorder;
186 }
187
188
189
190 this.latestClosestNeighbor = closestNeighbor;
191 return closestNeighbor;
192 }
193
194
195
196 public void clearHistory() {
197 abscissae.clear();
198 values.clear();
199 }
200
201
202
203
204
205 public void addGridPoint(final AbsoluteDate date, final double value) {
206
207 if (abscissae.isEmpty()) {
208 abscissae.add(date);
209 values.add(value);
210 }
211
212 else if (abscissae.contains(date)) {
213 values.set(abscissae.indexOf(date), value);
214 }
215
216
217 else {
218 final int closestNeighbor = getClosestNeighbor(date);
219 final int index = (date.compareTo(abscissae.get(closestNeighbor)) < 0) ? closestNeighbor : closestNeighbor + 1;
220 abscissae.add(index, date);
221 values.add(index, value);
222 }
223 }
224 }