1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
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.ode.EquationsMapper;
25
26 /** This class is a step interpolator that does nothing.
27 *
28 * <p>This class is used when the {@link StepHandler "step handler"}
29 * set up by the user does not need step interpolation. It does not
30 * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime
31 * setInterpolatedTime} is called. This implies the interpolated state
32 * is always the state at the end of the current step.</p>
33 *
34 * @see StepHandler
35 *
36 * @since 1.2
37 */
38
39 public class DummyStepInterpolator
40 extends AbstractStepInterpolator {
41
42 /** Serializable version identifier. */
43 private static final long serialVersionUID = 1708010296707839488L;
44
45 /** Current derivative. */
46 private double[] currentDerivative;
47
48 /** Simple constructor.
49 * This constructor builds an instance that is not usable yet, the
50 * <code>AbstractStepInterpolator.reinitialize</code> protected method
51 * should be called before using the instance in order to initialize
52 * the internal arrays. This constructor is used only in order to delay
53 * the initialization in some cases. As an example, the {@link
54 * org.apache.commons.math4.legacy.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses
55 * the prototyping design pattern to create the step interpolators by
56 * cloning an uninitialized model and latter initializing the copy.
57 */
58 public DummyStepInterpolator() {
59 super();
60 currentDerivative = null;
61 }
62
63 /** Simple constructor.
64 * @param y reference to the integrator array holding the state at
65 * the end of the step
66 * @param yDot reference to the integrator array holding the state
67 * derivative at some arbitrary point within the step
68 * @param forward integration direction indicator
69 */
70 public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) {
71 super(y, forward, new EquationsMapper(0, y.length), new EquationsMapper[0]);
72 currentDerivative = yDot;
73 }
74
75 /** Copy constructor.
76 * @param interpolator interpolator to copy from. The copy is a deep
77 * copy: its arrays are separated from the original arrays of the
78 * instance
79 */
80 public DummyStepInterpolator(final DummyStepInterpolator interpolator) {
81 super(interpolator);
82 if (interpolator.currentDerivative != null) {
83 currentDerivative = interpolator.currentDerivative.clone();
84 }
85 }
86
87 /** Really copy the finalized instance.
88 * @return a copy of the finalized instance
89 */
90 @Override
91 protected StepInterpolator doCopy() {
92 return new DummyStepInterpolator(this);
93 }
94
95 /** Compute the state at the interpolated time.
96 * In this class, this method does nothing: the interpolated state
97 * is always the state at the end of the current step.
98 * @param theta normalized interpolation abscissa within the step
99 * (theta is zero at the previous time step and one at the current time step)
100 * @param oneMinusThetaH time gap between the interpolated time and
101 * the current time
102 */
103 @Override
104 protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) {
105 System.arraycopy(currentState, 0, interpolatedState, 0, currentState.length);
106 System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length);
107 }
108
109 /** Write the instance to an output channel.
110 * @param out output channel
111 * @exception IOException if the instance cannot be written
112 */
113 @Override
114 public void writeExternal(final ObjectOutput out)
115 throws IOException {
116
117 // save the state of the base class
118 writeBaseExternal(out);
119
120 if (currentDerivative != null) {
121 for (int i = 0; i < currentDerivative.length; ++i) {
122 out.writeDouble(currentDerivative[i]);
123 }
124 }
125 }
126
127 /** Read the instance from an input channel.
128 * @param in input channel
129 * @exception IOException if the instance cannot be read
130 */
131 @Override
132 public void readExternal(final ObjectInput in)
133 throws IOException, ClassNotFoundException {
134
135 // read the base class
136 final double t = readBaseExternal(in);
137
138 if (currentState == null) {
139 currentDerivative = null;
140 } else {
141 currentDerivative = new double[currentState.length];
142 for (int i = 0; i < currentDerivative.length; ++i) {
143 currentDerivative[i] = in.readDouble();
144 }
145 }
146
147 // we can now set the interpolated time and state
148 setInterpolatedTime(t);
149 }
150 }