1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.orekit.rugged.adjustment;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.hipparchus.Field;
28 import org.hipparchus.analysis.differentiation.Gradient;
29 import org.hipparchus.analysis.differentiation.GradientField;
30 import org.hipparchus.optim.ConvergenceChecker;
31 import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresProblem;
32 import org.hipparchus.optim.nonlinear.vector.leastsquares.MultivariateJacobianFunction;
33 import org.hipparchus.optim.nonlinear.vector.leastsquares.ParameterValidator;
34 import org.orekit.rugged.adjustment.measurements.Observables;
35 import org.orekit.rugged.errors.RuggedException;
36 import org.orekit.rugged.errors.RuggedMessages;
37 import org.orekit.rugged.linesensor.LineSensor;
38 import org.orekit.rugged.utils.DerivativeGenerator;
39 import org.orekit.utils.ParameterDriver;
40
41
42
43
44
45
46
47
48
49
50 abstract class OptimizationProblemBuilder {
51
52
53 protected static final int ESTIMATION_LINE_RANGE_MARGIN = 100;
54
55
56 private final DerivativeGenerator<Gradient> generator;
57
58
59 private final List<ParameterDriver> drivers;
60
61
62 private final int nbParams;
63
64
65 private Observables measurements;
66
67
68 private final List<LineSensor> sensors;
69
70
71
72
73
74 OptimizationProblemBuilder(final List<LineSensor> sensors, final Observables measurements) {
75
76 this.generator = this.createGenerator(sensors);
77 this.drivers = this.generator.getSelected();
78 this.nbParams = this.drivers.size();
79 if (this.nbParams == 0) {
80 throw new RuggedException(RuggedMessages.NO_PARAMETERS_SELECTED);
81 }
82 this.measurements = measurements;
83 this.sensors = sensors;
84 }
85
86
87
88
89
90
91
92 public abstract LeastSquaresProblem build(int maxEvaluations, double convergenceThreshold);
93
94
95
96
97
98
99
100
101 final ConvergenceChecker<LeastSquaresProblem.Evaluation>
102 createChecker(final double parametersConvergenceThreshold) {
103
104 final ConvergenceChecker<LeastSquaresProblem.Evaluation> checker = (iteration, previous, current)
105 -> current.getPoint().getLInfDistance(previous.getPoint()) <= parametersConvergenceThreshold;
106
107 return checker;
108 }
109
110
111
112
113 final double[] createStartTab() {
114
115
116 final double[] start = new double[this.nbParams];
117 int iStart = 0;
118 for (final ParameterDriver driver : this.drivers) {
119 start[iStart++] = driver.getNormalizedValue();
120 }
121 return start;
122 }
123
124
125 protected abstract void createTargetAndWeight();
126
127
128
129
130 protected abstract MultivariateJacobianFunction createFunction();
131
132
133 protected abstract void initMapping();
134
135
136
137
138 final ParameterValidator createParameterValidator() {
139
140
141 final ParameterValidator validator = params -> {
142 int i = 0;
143 for (final ParameterDriver driver : this.drivers) {
144
145
146 driver.setNormalizedValue(params.getEntry(i));
147 params.setEntry(i++, driver.getNormalizedValue());
148 }
149 return params;
150 };
151
152 return validator;
153 }
154
155
156
157
158
159 private DerivativeGenerator<Gradient> createGenerator(final List<LineSensor> selectedSensors) {
160
161
162 final Set<String> names = new HashSet<>();
163
164
165 for (final LineSensor sensor : selectedSensors) {
166
167
168 sensor.getParametersDrivers().forEach(driver -> {
169
170
171 if (names.contains(driver.getName()) == false) {
172 names.add(driver.getName());
173 }
174 });
175 }
176
177
178 final List<ParameterDriver> selected = new ArrayList<>();
179 final Map<String, Integer> map = new HashMap<>();
180
181
182 for (final LineSensor sensor : selectedSensors) {
183
184 sensor.getParametersDrivers().filter(driver -> driver.isSelected()).forEach(driver -> {
185 if (map.get(driver.getName()) == null) {
186 map.put(driver.getName(), map.size());
187 selected.add(driver);
188 }
189 });
190 }
191
192
193 final GradientField field = GradientField.getField(map.size());
194 return new DerivativeGenerator<Gradient>() {
195
196
197 @Override
198 public List<ParameterDriver> getSelected() {
199 return selected;
200 }
201
202
203 @Override
204 public Gradient constant(final double value) {
205 return Gradient.constant(map.size(), value);
206 }
207
208
209 @Override
210 public Gradient variable(final ParameterDriver driver) {
211 final Integer index = map.get(driver.getName());
212 if (index == null) {
213 return constant(driver.getValue());
214 } else {
215 return Gradient.variable(map.size(), index.intValue(), driver.getValue());
216 }
217 }
218
219
220 @Override
221 public Field<Gradient> getField() {
222 return field;
223 }
224
225 };
226 }
227
228
229
230
231 protected List<LineSensor> getSensors() {
232 return sensors;
233 }
234
235
236
237
238 protected final int getNbParams() {
239 return this.nbParams;
240 }
241
242
243
244
245
246 protected final List<ParameterDriver> getDrivers() {
247 return this.drivers;
248 }
249
250
251
252
253
254 protected final DerivativeGenerator<Gradient> getGenerator() {
255 return this.generator;
256 }
257
258
259
260
261 protected Observables getMeasurements() {
262 return measurements;
263 }
264 }