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 org.hipparchus.exception.LocalizedCoreFormats;
20 import org.hipparchus.exception.MathIllegalArgumentException;
21 import org.hipparchus.linear.MatrixDecomposer;
22 import org.hipparchus.linear.MatrixUtils;
23 import org.hipparchus.linear.RealMatrix;
24 import org.hipparchus.util.MathUtils;
25
26
27
28
29
30
31
32
33
34 public class TaylorMap implements DifferentialAlgebra {
35
36
37 private final double[] point;
38
39
40 private final DerivativeStructure[] functions;
41
42
43
44
45
46
47
48
49
50 public TaylorMap(final double[] point, final DerivativeStructure[] functions) {
51 if (point == null || point.length == 0) {
52 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE,
53 point == null ? 0 : point.length);
54 }
55 if (functions == null || functions.length == 0) {
56 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE,
57 functions == null ? 0 : functions.length);
58 }
59 this.point = point.clone();
60 this.functions = functions.clone();
61 final DSFactory factory0 = functions[0].getFactory();
62 MathUtils.checkDimension(point.length, factory0.getCompiler().getFreeParameters());
63 for (int i = 1; i < functions.length; ++i) {
64 factory0.checkCompatibility(functions[i].getFactory());
65 }
66 }
67
68
69
70
71
72
73
74
75
76 public TaylorMap(final int parameters, final int order, final int nbFunctions) {
77 this(parameters, nbFunctions);
78 final DSFactory factory = new DSFactory(parameters, order);
79 for (int i = 0; i < nbFunctions; ++i) {
80 functions[i] = factory.variable(i, 0.0);
81 }
82 }
83
84
85
86
87
88 private TaylorMap(final int parameters, final int nbFunctions) {
89 this.point = new double[parameters];
90 this.functions = new DerivativeStructure[nbFunctions];
91 }
92
93
94 @Override
95 public int getFreeParameters() {
96 return point.length;
97 }
98
99
100 @Override
101 public int getOrder() {
102 return functions[0].getOrder();
103 }
104
105
106
107
108 public int getNbFunctions() {
109 return functions.length;
110 }
111
112
113
114
115 public double[] getPoint() {
116 return point.clone();
117 }
118
119
120
121
122
123 public DerivativeStructure getFunction(final int i) {
124 return functions[i];
125 }
126
127
128
129
130
131 private TaylorMap subtract(final TaylorMap map) {
132 final TaylorMap result = new TaylorMap(point.length, functions.length);
133 for (int i = 0; i < result.functions.length; ++i) {
134 result.functions[i] = functions[i].subtract(map.functions[i]);
135 }
136 return result;
137 }
138
139
140
141
142
143 public double[] value(final double... deltaP) {
144 final double[] value = new double[functions.length];
145 for (int i = 0; i < functions.length; ++i) {
146 value[i] = functions[i].taylor(deltaP);
147 }
148 return value;
149 }
150
151
152
153
154
155 public TaylorMap compose(final TaylorMap other) {
156
157
158 MathUtils.checkDimension(getFreeParameters(), other.getNbFunctions());
159
160 final DerivativeStructure[] composed = new DerivativeStructure[functions.length];
161 for (int i = 0; i < functions.length; ++i) {
162 composed[i] = functions[i].rebase(other.functions);
163 }
164
165 return new TaylorMap(other.point, composed);
166
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 public TaylorMap invert(final MatrixDecomposer decomposer) {
188
189 final DSFactory factory = functions[0].getFactory();
190 final DSCompiler compiler = factory.getCompiler();
191 final int n = functions.length;
192
193
194 MathUtils.checkDimension(n, functions[0].getFreeParameters());
195
196
197 final int[] indirection = new int[n];
198 int linearIndex = 0;
199 for (int k = 1; linearIndex < n; ++k) {
200 if (compiler.getPartialDerivativeOrdersSum(k) == 1) {
201 indirection[linearIndex++] = k;
202 }
203 }
204
205
206 final RealMatrix linear = MatrixUtils.createRealMatrix(n, n);
207 final TaylorMap nonLinearTM = new TaylorMap(n, n);
208 for (int i = 0; i < n; ++i) {
209 nonLinearTM.functions[i] = factory.build(functions[i].getAllDerivatives());
210 nonLinearTM.functions[i].setDerivativeComponent(0, 0.0);
211 for (int j = 0; j < n; ++j) {
212 final int k = indirection[j];
213 linear.setEntry(i, j, functions[i].getDerivativeComponent(k));
214 nonLinearTM.functions[i].setDerivativeComponent(k, 0.0);
215 }
216 }
217
218
219 final RealMatrix linearInvert = decomposer.decompose(linear).getInverse();
220
221
222 final TaylorMap linearInvertTM = new TaylorMap(n, n);
223 for (int i = 0; i < n; ++i) {
224 linearInvertTM.functions[i] = new DerivativeStructure(factory);
225 for (int j = 0; j < n; ++j) {
226 linearInvertTM.functions[i].setDerivativeComponent(indirection[j], linearInvert.getEntry(i, j));
227 }
228 }
229
230
231
232 final TaylorMap identity = new TaylorMap(n, compiler.getOrder(), n);
233 TaylorMap invertTM = linearInvertTM;
234 for (int k = 1; k < compiler.getOrder(); ++k) {
235 invertTM = linearInvertTM.compose(identity.subtract(nonLinearTM.compose(invertTM)));
236 }
237
238
239 for (int i = 0; i < n; ++i) {
240 invertTM.point[i] = functions[i].getValue();
241 invertTM.functions[i].setDerivativeComponent(0, point[i]);
242 }
243
244 return invertTM;
245
246 }
247
248 }