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.sampling;
19
20 import java.io.IOException;
21 import java.io.ObjectInput;
22 import java.io.ObjectOutput;
23
24 import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
25 import org.apache.commons.math4.legacy.ode.EquationsMapper;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public abstract class AbstractStepInterpolator
44 implements StepInterpolator {
45
46
47 protected double h;
48
49
50 protected double[] currentState;
51
52
53 protected double interpolatedTime;
54
55
56 protected double[] interpolatedState;
57
58
59 protected double[] interpolatedDerivatives;
60
61
62 protected double[] interpolatedPrimaryState;
63
64
65 protected double[] interpolatedPrimaryDerivatives;
66
67
68 protected double[][] interpolatedSecondaryState;
69
70
71 protected double[][] interpolatedSecondaryDerivatives;
72
73
74 private double globalPreviousTime;
75
76
77 private double globalCurrentTime;
78
79
80 private double softPreviousTime;
81
82
83 private double softCurrentTime;
84
85
86 private boolean finalized;
87
88
89 private boolean forward;
90
91
92 private boolean dirtyState;
93
94
95 private EquationsMapper primaryMapper;
96
97
98 private EquationsMapper[] secondaryMappers;
99
100
101
102
103
104
105
106
107
108
109
110
111 protected AbstractStepInterpolator() {
112 globalPreviousTime = Double.NaN;
113 globalCurrentTime = Double.NaN;
114 softPreviousTime = Double.NaN;
115 softCurrentTime = Double.NaN;
116 h = Double.NaN;
117 interpolatedTime = Double.NaN;
118 currentState = null;
119 finalized = false;
120 this.forward = true;
121 this.dirtyState = true;
122 primaryMapper = null;
123 secondaryMappers = null;
124 allocateInterpolatedArrays(-1);
125 }
126
127
128
129
130
131
132
133
134 protected AbstractStepInterpolator(final double[] y, final boolean forward,
135 final EquationsMapper primaryMapper,
136 final EquationsMapper[] secondaryMappers) {
137
138 globalPreviousTime = Double.NaN;
139 globalCurrentTime = Double.NaN;
140 softPreviousTime = Double.NaN;
141 softCurrentTime = Double.NaN;
142 h = Double.NaN;
143 interpolatedTime = Double.NaN;
144 currentState = y;
145 finalized = false;
146 this.forward = forward;
147 this.dirtyState = true;
148 this.primaryMapper = primaryMapper;
149 this.secondaryMappers = (secondaryMappers == null) ? null : secondaryMappers.clone();
150 allocateInterpolatedArrays(y.length);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 protected AbstractStepInterpolator(final AbstractStepInterpolator interpolator) {
171
172 globalPreviousTime = interpolator.globalPreviousTime;
173 globalCurrentTime = interpolator.globalCurrentTime;
174 softPreviousTime = interpolator.softPreviousTime;
175 softCurrentTime = interpolator.softCurrentTime;
176 h = interpolator.h;
177 interpolatedTime = interpolator.interpolatedTime;
178
179 if (interpolator.currentState == null) {
180 currentState = null;
181 primaryMapper = null;
182 secondaryMappers = null;
183 allocateInterpolatedArrays(-1);
184 } else {
185 currentState = interpolator.currentState.clone();
186 interpolatedState = interpolator.interpolatedState.clone();
187 interpolatedDerivatives = interpolator.interpolatedDerivatives.clone();
188 interpolatedPrimaryState = interpolator.interpolatedPrimaryState.clone();
189 interpolatedPrimaryDerivatives = interpolator.interpolatedPrimaryDerivatives.clone();
190 interpolatedSecondaryState = new double[interpolator.interpolatedSecondaryState.length][];
191 interpolatedSecondaryDerivatives = new double[interpolator.interpolatedSecondaryDerivatives.length][];
192 for (int i = 0; i < interpolatedSecondaryState.length; ++i) {
193 interpolatedSecondaryState[i] = interpolator.interpolatedSecondaryState[i].clone();
194 interpolatedSecondaryDerivatives[i] = interpolator.interpolatedSecondaryDerivatives[i].clone();
195 }
196 }
197
198 finalized = interpolator.finalized;
199 forward = interpolator.forward;
200 dirtyState = interpolator.dirtyState;
201 primaryMapper = interpolator.primaryMapper;
202 secondaryMappers = (interpolator.secondaryMappers == null) ?
203 null : interpolator.secondaryMappers.clone();
204 }
205
206
207
208
209 private void allocateInterpolatedArrays(final int dimension) {
210 if (dimension < 0) {
211 interpolatedState = null;
212 interpolatedDerivatives = null;
213 interpolatedPrimaryState = null;
214 interpolatedPrimaryDerivatives = null;
215 interpolatedSecondaryState = null;
216 interpolatedSecondaryDerivatives = null;
217 } else {
218 interpolatedState = new double[dimension];
219 interpolatedDerivatives = new double[dimension];
220 interpolatedPrimaryState = new double[primaryMapper.getDimension()];
221 interpolatedPrimaryDerivatives = new double[primaryMapper.getDimension()];
222 if (secondaryMappers == null) {
223 interpolatedSecondaryState = null;
224 interpolatedSecondaryDerivatives = null;
225 } else {
226 interpolatedSecondaryState = new double[secondaryMappers.length][];
227 interpolatedSecondaryDerivatives = new double[secondaryMappers.length][];
228 for (int i = 0; i < secondaryMappers.length; ++i) {
229 interpolatedSecondaryState[i] = new double[secondaryMappers[i].getDimension()];
230 interpolatedSecondaryDerivatives[i] = new double[secondaryMappers[i].getDimension()];
231 }
232 }
233 }
234 }
235
236
237
238
239
240
241
242 protected void reinitialize(final double[] y, final boolean isForward,
243 final EquationsMapper primary,
244 final EquationsMapper[] secondary) {
245
246 globalPreviousTime = Double.NaN;
247 globalCurrentTime = Double.NaN;
248 softPreviousTime = Double.NaN;
249 softCurrentTime = Double.NaN;
250 h = Double.NaN;
251 interpolatedTime = Double.NaN;
252 currentState = y;
253 finalized = false;
254 this.forward = isForward;
255 this.dirtyState = true;
256 this.primaryMapper = primary;
257 this.secondaryMappers = secondary.clone();
258 allocateInterpolatedArrays(y.length);
259 }
260
261
262 @Override
263 public StepInterpolator copy() throws MaxCountExceededException {
264
265
266 finalizeStep();
267
268
269 return doCopy();
270 }
271
272
273
274
275
276
277
278
279 protected abstract StepInterpolator doCopy();
280
281
282
283
284
285 public void shift() {
286 globalPreviousTime = globalCurrentTime;
287 softPreviousTime = globalPreviousTime;
288 softCurrentTime = globalCurrentTime;
289 }
290
291
292
293
294 public void storeTime(final double t) {
295
296 globalCurrentTime = t;
297 softCurrentTime = globalCurrentTime;
298 h = globalCurrentTime - globalPreviousTime;
299 setInterpolatedTime(t);
300
301
302 finalized = false;
303 }
304
305
306
307
308
309
310
311
312
313
314
315 public void setSoftPreviousTime(final double softPreviousTime) {
316 this.softPreviousTime = softPreviousTime;
317 }
318
319
320
321
322
323
324
325
326
327
328
329 public void setSoftCurrentTime(final double softCurrentTime) {
330 this.softCurrentTime = softCurrentTime;
331 }
332
333
334
335
336
337 public double getGlobalPreviousTime() {
338 return globalPreviousTime;
339 }
340
341
342
343
344
345 public double getGlobalCurrentTime() {
346 return globalCurrentTime;
347 }
348
349
350
351
352
353
354 @Override
355 public double getPreviousTime() {
356 return softPreviousTime;
357 }
358
359
360
361
362
363
364 @Override
365 public double getCurrentTime() {
366 return softCurrentTime;
367 }
368
369
370 @Override
371 public double getInterpolatedTime() {
372 return interpolatedTime;
373 }
374
375
376 @Override
377 public void setInterpolatedTime(final double time) {
378 interpolatedTime = time;
379 dirtyState = true;
380 }
381
382
383 @Override
384 public boolean isForward() {
385 return forward;
386 }
387
388
389
390
391
392
393
394
395
396
397 protected abstract void computeInterpolatedStateAndDerivatives(double theta,
398 double oneMinusThetaH)
399 throws MaxCountExceededException;
400
401
402
403
404 private void evaluateCompleteInterpolatedState()
405 throws MaxCountExceededException {
406
407 if (dirtyState) {
408 final double oneMinusThetaH = globalCurrentTime - interpolatedTime;
409 final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h;
410 computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH);
411 dirtyState = false;
412 }
413 }
414
415
416 @Override
417 public double[] getInterpolatedState() throws MaxCountExceededException {
418 evaluateCompleteInterpolatedState();
419 primaryMapper.extractEquationData(interpolatedState,
420 interpolatedPrimaryState);
421 return interpolatedPrimaryState;
422 }
423
424
425 @Override
426 public double[] getInterpolatedDerivatives() throws MaxCountExceededException {
427 evaluateCompleteInterpolatedState();
428 primaryMapper.extractEquationData(interpolatedDerivatives,
429 interpolatedPrimaryDerivatives);
430 return interpolatedPrimaryDerivatives;
431 }
432
433
434 @Override
435 public double[] getInterpolatedSecondaryState(final int index) throws MaxCountExceededException {
436 evaluateCompleteInterpolatedState();
437 secondaryMappers[index].extractEquationData(interpolatedState,
438 interpolatedSecondaryState[index]);
439 return interpolatedSecondaryState[index];
440 }
441
442
443 @Override
444 public double[] getInterpolatedSecondaryDerivatives(final int index) throws MaxCountExceededException {
445 evaluateCompleteInterpolatedState();
446 secondaryMappers[index].extractEquationData(interpolatedDerivatives,
447 interpolatedSecondaryDerivatives[index]);
448 return interpolatedSecondaryDerivatives[index];
449 }
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492 public final void finalizeStep() throws MaxCountExceededException {
493 if (! finalized) {
494 doFinalize();
495 finalized = true;
496 }
497 }
498
499
500
501
502
503
504 protected void doFinalize() throws MaxCountExceededException {
505 }
506
507
508 @Override
509 public abstract void writeExternal(ObjectOutput out)
510 throws IOException;
511
512
513 @Override
514 public abstract void readExternal(ObjectInput in)
515 throws IOException, ClassNotFoundException;
516
517
518
519
520
521
522
523 protected void writeBaseExternal(final ObjectOutput out)
524 throws IOException {
525
526 if (currentState == null) {
527 out.writeInt(-1);
528 } else {
529 out.writeInt(currentState.length);
530 }
531 out.writeDouble(globalPreviousTime);
532 out.writeDouble(globalCurrentTime);
533 out.writeDouble(softPreviousTime);
534 out.writeDouble(softCurrentTime);
535 out.writeDouble(h);
536 out.writeBoolean(forward);
537 out.writeObject(primaryMapper);
538 out.write(secondaryMappers.length);
539 for (final EquationsMapper mapper : secondaryMappers) {
540 out.writeObject(mapper);
541 }
542
543 if (currentState != null) {
544 for (int i = 0; i < currentState.length; ++i) {
545 out.writeDouble(currentState[i]);
546 }
547 }
548
549 out.writeDouble(interpolatedTime);
550
551
552
553
554 try {
555
556 finalizeStep();
557 } catch (MaxCountExceededException mcee) {
558 final IOException ioe = new IOException(mcee.getLocalizedMessage());
559 ioe.initCause(mcee);
560 throw ioe;
561 }
562 }
563
564
565
566
567
568
569
570
571
572
573
574
575 protected double readBaseExternal(final ObjectInput in)
576 throws IOException, ClassNotFoundException {
577
578 final int dimension = in.readInt();
579 globalPreviousTime = in.readDouble();
580 globalCurrentTime = in.readDouble();
581 softPreviousTime = in.readDouble();
582 softCurrentTime = in.readDouble();
583 h = in.readDouble();
584 forward = in.readBoolean();
585 primaryMapper = (EquationsMapper) in.readObject();
586 secondaryMappers = new EquationsMapper[in.read()];
587 for (int i = 0; i < secondaryMappers.length; ++i) {
588 secondaryMappers[i] = (EquationsMapper) in.readObject();
589 }
590 dirtyState = true;
591
592 if (dimension < 0) {
593 currentState = null;
594 } else {
595 currentState = new double[dimension];
596 for (int i = 0; i < currentState.length; ++i) {
597 currentState[i] = in.readDouble();
598 }
599 }
600
601
602 interpolatedTime = Double.NaN;
603 allocateInterpolatedArrays(dimension);
604
605 finalized = true;
606
607 return in.readDouble();
608 }
609 }