1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.analysis.differentiation;
18
19 import java.lang.reflect.Array;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.Field;
23 import org.hipparchus.exception.LocalizedCoreFormats;
24 import org.hipparchus.exception.MathIllegalArgumentException;
25 import org.hipparchus.linear.FieldMatrix;
26 import org.hipparchus.linear.FieldMatrixDecomposer;
27 import org.hipparchus.linear.MatrixUtils;
28 import org.hipparchus.util.MathArrays;
29 import org.hipparchus.util.MathUtils;
30
31
32
33
34
35
36
37
38
39
40 public class FieldTaylorMap<T extends CalculusFieldElement<T>> implements DifferentialAlgebra {
41
42
43 private final T[] point;
44
45
46 private final FieldDerivativeStructure<T>[] functions;
47
48
49
50
51
52
53
54
55
56 public FieldTaylorMap(final T[] point, final FieldDerivativeStructure<T>[] functions) {
57 if (point == null || point.length == 0) {
58 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE,
59 point == null ? 0 : point.length);
60 }
61 if (functions == null || functions.length == 0) {
62 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE,
63 functions == null ? 0 : functions.length);
64 }
65 this.point = point.clone();
66 this.functions = functions.clone();
67 final FDSFactory<T> factory0 = functions[0].getFactory();
68 MathUtils.checkDimension(point.length, factory0.getCompiler().getFreeParameters());
69 for (int i = 1; i < functions.length; ++i) {
70 factory0.checkCompatibility(functions[i].getFactory());
71 }
72 }
73
74
75
76
77
78
79
80
81
82
83 public FieldTaylorMap(final Field<T> valueField, final int parameters, final int order, final int nbFunctions) {
84 this(valueField, parameters, nbFunctions);
85 final FDSFactory<T> factory = new FDSFactory<>(valueField, parameters, order);
86 for (int i = 0; i < nbFunctions; ++i) {
87 functions[i] = factory.variable(i, 0.0);
88 }
89 }
90
91
92
93
94
95
96 @SuppressWarnings("unchecked")
97 private FieldTaylorMap(final Field<T> valueField, final int parameters, final int nbFunctions) {
98 this.point = MathArrays.buildArray(valueField, parameters);
99 this.functions = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, nbFunctions);
100 }
101
102
103 @Override
104 public int getFreeParameters() {
105 return point.length;
106 }
107
108
109 @Override
110 public int getOrder() {
111 return functions[0].getOrder();
112 }
113
114
115
116
117 @Deprecated
118 public int getNbParameters() {
119 return getFreeParameters();
120 }
121
122
123
124
125 public int getNbFunctions() {
126 return functions.length;
127 }
128
129
130
131
132 public T[] getPoint() {
133 return point.clone();
134 }
135
136
137
138
139
140 public FieldDerivativeStructure<T> getFunction(final int i) {
141 return functions[i];
142 }
143
144
145
146
147
148 private FieldTaylorMap<T> subtract(final FieldTaylorMap<T> map) {
149 final FieldTaylorMap<T> result = new FieldTaylorMap<>(functions[0].getFactory().getValueField(),
150 point.length, functions.length);
151 for (int i = 0; i < result.functions.length; ++i) {
152 result.functions[i] = functions[i].subtract(map.functions[i]);
153 }
154 return result;
155 }
156
157
158
159
160
161 public T[] value(final double... deltaP) {
162 final T[] value = MathArrays.buildArray(functions[0].getFactory().getValueField(), functions.length);
163 for (int i = 0; i < functions.length; ++i) {
164 value[i] = functions[i].taylor(deltaP);
165 }
166 return value;
167 }
168
169
170
171
172
173 public T[] value(@SuppressWarnings("unchecked") final T... deltaP) {
174 final T[] value = MathArrays.buildArray(functions[0].getFactory().getValueField(), functions.length);
175 for (int i = 0; i < functions.length; ++i) {
176 value[i] = functions[i].taylor(deltaP);
177 }
178 return value;
179 }
180
181
182
183
184
185 public FieldTaylorMap<T> compose(final FieldTaylorMap<T> other) {
186
187
188 MathUtils.checkDimension(getFreeParameters(), other.getNbFunctions());
189
190 @SuppressWarnings("unchecked")
191 final FieldDerivativeStructure<T>[] composed = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class,
192 functions.length);
193 for (int i = 0; i < functions.length; ++i) {
194 composed[i] = functions[i].rebase(other.functions);
195 }
196
197 return new FieldTaylorMap<>(other.point, composed);
198
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 public FieldTaylorMap<T> invert(final FieldMatrixDecomposer<T> decomposer) {
220
221 final FDSFactory<T> factory = functions[0].getFactory();
222 final Field<T> field = factory.getValueField();
223 final DSCompiler compiler = factory.getCompiler();
224 final int n = functions.length;
225
226
227 MathUtils.checkDimension(n, functions[0].getFreeParameters());
228
229
230 final int[] indirection = new int[n];
231 int linearIndex = 0;
232 for (int k = 1; linearIndex < n; ++k) {
233 if (compiler.getPartialDerivativeOrdersSum(k) == 1) {
234 indirection[linearIndex++] = k;
235 }
236 }
237
238
239 final FieldMatrix<T> linear = MatrixUtils.createFieldMatrix(field, n, n);
240 final FieldTaylorMap<T> nonLinearTM = new FieldTaylorMap<>(field, n, n);
241 for (int i = 0; i < n; ++i) {
242 nonLinearTM.functions[i] = factory.build(functions[i].getAllDerivatives());
243 nonLinearTM.functions[i].setDerivativeComponent(0, field.getZero());
244 for (int j = 0; j < n; ++j) {
245 final int k = indirection[j];
246 linear.setEntry(i, j, functions[i].getDerivativeComponent(k));
247 nonLinearTM.functions[i].setDerivativeComponent(k, field.getZero());
248 }
249 }
250
251
252 final FieldMatrix<T> linearInvert = decomposer.decompose(linear).getInverse();
253
254
255 final FieldTaylorMap<T> linearInvertTM = new FieldTaylorMap<>(field, n, n);
256 for (int i = 0; i < n; ++i) {
257 linearInvertTM.functions[i] = new FieldDerivativeStructure<>(factory);
258 for (int j = 0; j < n; ++j) {
259 linearInvertTM.functions[i].setDerivativeComponent(indirection[j], linearInvert.getEntry(i, j));
260 }
261 }
262
263
264
265 final FieldTaylorMap<T> identity = new FieldTaylorMap<>(field, n, compiler.getOrder(), n);
266 FieldTaylorMap<T> invertTM = linearInvertTM;
267 for (int k = 1; k < compiler.getOrder(); ++k) {
268 invertTM = linearInvertTM.compose(identity.subtract(nonLinearTM.compose(invertTM)));
269 }
270
271
272 for (int i = 0; i < n; ++i) {
273 invertTM.point[i] = functions[i].getValue();
274 invertTM.functions[i].setDerivativeComponent(0, point[i]);
275 }
276
277 return invertTM;
278
279 }
280
281 }