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 public int getNbFunctions() {
118 return functions.length;
119 }
120
121
122
123
124 public T[] getPoint() {
125 return point.clone();
126 }
127
128
129
130
131
132 public FieldDerivativeStructure<T> getFunction(final int i) {
133 return functions[i];
134 }
135
136
137
138
139
140 private FieldTaylorMap<T> subtract(final FieldTaylorMap<T> map) {
141 final FieldTaylorMap<T> result = new FieldTaylorMap<>(functions[0].getFactory().getValueField(),
142 point.length, functions.length);
143 for (int i = 0; i < result.functions.length; ++i) {
144 result.functions[i] = functions[i].subtract(map.functions[i]);
145 }
146 return result;
147 }
148
149
150
151
152
153 public T[] value(final double... deltaP) {
154 final T[] value = MathArrays.buildArray(functions[0].getFactory().getValueField(), functions.length);
155 for (int i = 0; i < functions.length; ++i) {
156 value[i] = functions[i].taylor(deltaP);
157 }
158 return value;
159 }
160
161
162
163
164
165 public T[] value(@SuppressWarnings("unchecked") final T... deltaP) {
166 final T[] value = MathArrays.buildArray(functions[0].getFactory().getValueField(), functions.length);
167 for (int i = 0; i < functions.length; ++i) {
168 value[i] = functions[i].taylor(deltaP);
169 }
170 return value;
171 }
172
173
174
175
176
177 public FieldTaylorMap<T> compose(final FieldTaylorMap<T> other) {
178
179
180 MathUtils.checkDimension(getFreeParameters(), other.getNbFunctions());
181
182 @SuppressWarnings("unchecked")
183 final FieldDerivativeStructure<T>[] composed = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class,
184 functions.length);
185 for (int i = 0; i < functions.length; ++i) {
186 composed[i] = functions[i].rebase(other.functions);
187 }
188
189 return new FieldTaylorMap<>(other.point, composed);
190
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 public FieldTaylorMap<T> invert(final FieldMatrixDecomposer<T> decomposer) {
212
213 final FDSFactory<T> factory = functions[0].getFactory();
214 final Field<T> field = factory.getValueField();
215 final DSCompiler compiler = factory.getCompiler();
216 final int n = functions.length;
217
218
219 MathUtils.checkDimension(n, functions[0].getFreeParameters());
220
221
222 final int[] indirection = new int[n];
223 int linearIndex = 0;
224 for (int k = 1; linearIndex < n; ++k) {
225 if (compiler.getPartialDerivativeOrdersSum(k) == 1) {
226 indirection[linearIndex++] = k;
227 }
228 }
229
230
231 final FieldMatrix<T> linear = MatrixUtils.createFieldMatrix(field, n, n);
232 final FieldTaylorMap<T> nonLinearTM = new FieldTaylorMap<>(field, n, n);
233 for (int i = 0; i < n; ++i) {
234 nonLinearTM.functions[i] = factory.build(functions[i].getAllDerivatives());
235 nonLinearTM.functions[i].setDerivativeComponent(0, field.getZero());
236 for (int j = 0; j < n; ++j) {
237 final int k = indirection[j];
238 linear.setEntry(i, j, functions[i].getDerivativeComponent(k));
239 nonLinearTM.functions[i].setDerivativeComponent(k, field.getZero());
240 }
241 }
242
243
244 final FieldMatrix<T> linearInvert = decomposer.decompose(linear).getInverse();
245
246
247 final FieldTaylorMap<T> linearInvertTM = new FieldTaylorMap<>(field, n, n);
248 for (int i = 0; i < n; ++i) {
249 linearInvertTM.functions[i] = new FieldDerivativeStructure<>(factory);
250 for (int j = 0; j < n; ++j) {
251 linearInvertTM.functions[i].setDerivativeComponent(indirection[j], linearInvert.getEntry(i, j));
252 }
253 }
254
255
256
257 final FieldTaylorMap<T> identity = new FieldTaylorMap<>(field, n, compiler.getOrder(), n);
258 FieldTaylorMap<T> invertTM = linearInvertTM;
259 for (int k = 1; k < compiler.getOrder(); ++k) {
260 invertTM = linearInvertTM.compose(identity.subtract(nonLinearTM.compose(invertTM)));
261 }
262
263
264 for (int i = 0; i < n; ++i) {
265 invertTM.point[i] = functions[i].getValue();
266 invertTM.functions[i].setDerivativeComponent(0, point[i]);
267 }
268
269 return invertTM;
270
271 }
272
273 }