1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical;
18
19 import java.util.Arrays;
20 import java.util.List;
21
22 import org.hipparchus.analysis.differentiation.Gradient;
23 import org.hipparchus.linear.MatrixUtils;
24 import org.hipparchus.linear.RealMatrix;
25 import org.orekit.orbits.FieldOrbit;
26 import org.orekit.propagation.AbstractMatricesHarvester;
27 import org.orekit.propagation.FieldSpacecraftState;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.utils.DoubleArrayDictionary;
32 import org.orekit.utils.FieldPVCoordinates;
33 import org.orekit.utils.ParameterDriver;
34
35
36
37
38
39
40
41
42 public abstract class AbstractAnalyticalMatricesHarvester extends AbstractMatricesHarvester {
43
44
45 private List<String> columnsNames;
46
47
48 private AbsoluteDate epoch;
49
50
51 private final double[][] analyticalDerivativesStm;
52
53
54 private final DoubleArrayDictionary analyticalDerivativesJacobianColumns;
55
56
57 private final AbstractAnalyticalPropagator propagator;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 protected AbstractAnalyticalMatricesHarvester(final AbstractAnalyticalPropagator propagator, final String stmName,
74 final RealMatrix initialStm, final DoubleArrayDictionary initialJacobianColumns) {
75 super(stmName, initialStm, initialJacobianColumns);
76 this.propagator = propagator;
77 this.epoch = propagator.getInitialState().getDate();
78 this.columnsNames = null;
79 this.analyticalDerivativesStm = getInitialStateTransitionMatrix().getData();
80 this.analyticalDerivativesJacobianColumns = new DoubleArrayDictionary();
81 }
82
83
84 @Override
85 public List<String> getJacobiansColumnsNames() {
86 return columnsNames == null ? propagator.getJacobiansColumnsNames() : columnsNames;
87 }
88
89
90 @Override
91 public void freezeColumnsNames() {
92 columnsNames = getJacobiansColumnsNames();
93 }
94
95
96 @Override
97 public RealMatrix getStateTransitionMatrix(final SpacecraftState state) {
98
99 updateDerivativesIfNeeded(state);
100
101 return MatrixUtils.createRealMatrix(analyticalDerivativesStm);
102 }
103
104
105 @Override
106 public RealMatrix getParametersJacobian(final SpacecraftState state) {
107
108 updateDerivativesIfNeeded(state);
109
110
111 final List<String> names = getJacobiansColumnsNames();
112 if (names == null || names.isEmpty()) {
113 return null;
114 }
115
116
117 final RealMatrix dYdP = MatrixUtils.createRealMatrix(STATE_DIMENSION, names.size());
118
119
120 for (int j = 0; j < names.size(); ++j) {
121 final double[] column = analyticalDerivativesJacobianColumns.get(names.get(j));
122 if (column != null) {
123 for (int i = 0; i < STATE_DIMENSION; i++) {
124 dYdP.addToEntry(i, j, column[i]);
125 }
126 }
127 }
128
129
130 return dYdP;
131 }
132
133
134 @Override
135 public void setReferenceState(final SpacecraftState reference) {
136
137
138 for (final double[] row : analyticalDerivativesStm) {
139 Arrays.fill(row, 0.0);
140 }
141 analyticalDerivativesJacobianColumns.clear();
142
143 final AbstractAnalyticalGradientConverter converter = getGradientConverter();
144 final FieldSpacecraftState<Gradient> gState = converter.getState();
145 final Gradient[] gParameters = converter.getParameters(gState);
146 final FieldAbstractAnalyticalPropagator<Gradient> gPropagator = converter.getPropagator(gState, gParameters);
147
148
149 final AbsoluteDate target = reference.getDate();
150 final FieldAbsoluteDate<Gradient> start = gPropagator.getInitialState().getDate();
151 final double dt = target.durationFrom(start.toAbsoluteDate());
152 final FieldOrbit<Gradient> gOrbit = gPropagator.propagateOrbit(start.shiftedBy(dt), gParameters);
153 final FieldPVCoordinates<Gradient> gPv = gOrbit.getPVCoordinates();
154
155 final double[] derivativesX = gPv.getPosition().getX().getGradient();
156 final double[] derivativesY = gPv.getPosition().getY().getGradient();
157 final double[] derivativesZ = gPv.getPosition().getZ().getGradient();
158 final double[] derivativesVx = gPv.getVelocity().getX().getGradient();
159 final double[] derivativesVy = gPv.getVelocity().getY().getGradient();
160 final double[] derivativesVz = gPv.getVelocity().getZ().getGradient();
161
162
163 addToRow(derivativesX, 0);
164 addToRow(derivativesY, 1);
165 addToRow(derivativesZ, 2);
166 addToRow(derivativesVx, 3);
167 addToRow(derivativesVy, 4);
168 addToRow(derivativesVz, 5);
169
170
171 int paramsIndex = converter.getFreeStateParameters();
172 for (ParameterDriver driver : converter.getParametersDrivers()) {
173 if (driver.isSelected()) {
174
175
176 DoubleArrayDictionary.Entry entry = analyticalDerivativesJacobianColumns.getEntry(driver.getName());
177 if (entry == null) {
178
179 analyticalDerivativesJacobianColumns.put(driver.getName(), new double[STATE_DIMENSION]);
180 entry = analyticalDerivativesJacobianColumns.getEntry(driver.getName());
181 }
182
183
184 entry.increment(new double[] {
185 derivativesX[paramsIndex], derivativesY[paramsIndex], derivativesZ[paramsIndex],
186 derivativesVx[paramsIndex], derivativesVy[paramsIndex], derivativesVz[paramsIndex]
187 });
188 ++paramsIndex;
189
190 }
191 }
192
193
194 epoch = target;
195
196 }
197
198
199
200
201 private void updateDerivativesIfNeeded(final SpacecraftState state) {
202 if (!state.getDate().isEqualTo(epoch)) {
203 setReferenceState(state);
204 }
205 }
206
207
208
209
210
211 private void addToRow(final double[] derivatives, final int index) {
212 for (int i = 0; i < 6; i++) {
213 analyticalDerivativesStm[index][i] += derivatives[i];
214 }
215 }
216
217
218
219
220
221 public abstract AbstractAnalyticalGradientConverter getGradientConverter();
222
223 }