1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.ode;
19
20 import java.io.Serializable;
21
22 import org.apache.commons.math4.legacy.core.RealFieldElement;
23 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
24 import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
25 import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
26 import org.apache.commons.math4.legacy.core.MathArrays;
27
28
29
30
31
32
33
34
35
36
37
38 public class FieldEquationsMapper<T extends RealFieldElement<T>> implements Serializable {
39
40
41 private static final long serialVersionUID = 20151114L;
42
43
44 private final int[] start;
45
46
47
48
49
50
51
52
53
54 FieldEquationsMapper(final FieldEquationsMapper<T> mapper, final int dimension) {
55 final int index = (mapper == null) ? 0 : mapper.getNumberOfEquations();
56 this.start = new int[index + 2];
57 if (mapper == null) {
58 start[0] = 0;
59 } else {
60 System.arraycopy(mapper.start, 0, start, 0, index + 1);
61 }
62 start[index + 1] = start[index] + dimension;
63 }
64
65
66
67
68 public int getNumberOfEquations() {
69 return start.length - 1;
70 }
71
72
73
74
75
76
77
78 public int getTotalDimension() {
79 return start[start.length - 1];
80 }
81
82
83
84
85
86 public T[] mapState(final FieldODEState<T> state) {
87 final T[] y = MathArrays.buildArray(state.getTime().getField(), getTotalDimension());
88 int index = 0;
89 insertEquationData(index, state.getState(), y);
90 while (++index < getNumberOfEquations()) {
91 insertEquationData(index, state.getSecondaryState(index), y);
92 }
93 return y;
94 }
95
96
97
98
99
100 public T[] mapDerivative(final FieldODEStateAndDerivative<T> state) {
101 final T[] yDot = MathArrays.buildArray(state.getTime().getField(), getTotalDimension());
102 int index = 0;
103 insertEquationData(index, state.getDerivative(), yDot);
104 while (++index < getNumberOfEquations()) {
105 insertEquationData(index, state.getSecondaryDerivative(index), yDot);
106 }
107 return yDot;
108 }
109
110
111
112
113
114
115
116
117 public FieldODEStateAndDerivative<T> mapStateAndDerivative(final T t, final T[] y, final T[] yDot)
118 throws DimensionMismatchException {
119
120 if (y.length != getTotalDimension()) {
121 throw new DimensionMismatchException(y.length, getTotalDimension());
122 }
123
124 if (yDot.length != getTotalDimension()) {
125 throw new DimensionMismatchException(yDot.length, getTotalDimension());
126 }
127
128 final int n = getNumberOfEquations();
129 int index = 0;
130 final T[] state = extractEquationData(index, y);
131 final T[] derivative = extractEquationData(index, yDot);
132 if (n < 2) {
133 return new FieldODEStateAndDerivative<>(t, state, derivative);
134 } else {
135 final T[][] secondaryState = MathArrays.buildArray(t.getField(), n - 1, -1);
136 final T[][] secondaryDerivative = MathArrays.buildArray(t.getField(), n - 1, -1);
137 while (++index < getNumberOfEquations()) {
138 secondaryState[index - 1] = extractEquationData(index, y);
139 secondaryDerivative[index - 1] = extractEquationData(index, yDot);
140 }
141 return new FieldODEStateAndDerivative<>(t, state, derivative, secondaryState, secondaryDerivative);
142 }
143 }
144
145
146
147
148
149
150
151
152
153
154 public T[] extractEquationData(final int index, final T[] complete)
155 throws MathIllegalArgumentException, DimensionMismatchException {
156 checkIndex(index);
157 final int begin = start[index];
158 final int end = start[index + 1];
159 if (complete.length < end) {
160 throw new DimensionMismatchException(complete.length, end);
161 }
162 final int dimension = end - begin;
163 final T[] equationData = MathArrays.buildArray(complete[0].getField(), dimension);
164 System.arraycopy(complete, begin, equationData, 0, dimension);
165 return equationData;
166 }
167
168
169
170
171
172
173
174
175
176 public void insertEquationData(final int index, T[] equationData, T[] complete)
177 throws DimensionMismatchException {
178 checkIndex(index);
179 final int begin = start[index];
180 final int end = start[index + 1];
181 final int dimension = end - begin;
182 if (complete.length < end) {
183 throw new DimensionMismatchException(complete.length, end);
184 }
185 if (equationData.length != dimension) {
186 throw new DimensionMismatchException(equationData.length, dimension);
187 }
188 System.arraycopy(equationData, 0, complete, begin, dimension);
189 }
190
191
192
193
194
195
196 private void checkIndex(final int index) throws MathIllegalArgumentException {
197 if (index < 0 || index > start.length - 2) {
198 throw new MathIllegalArgumentException(LocalizedFormats.ARGUMENT_OUTSIDE_DOMAIN,
199 index, 0, start.length - 2);
200 }
201 }
202 }