001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.math3.ode.sampling;
019
020import org.apache.commons.math3.RealFieldElement;
021import org.apache.commons.math3.exception.MaxCountExceededException;
022import org.apache.commons.math3.ode.FieldEquationsMapper;
023import org.apache.commons.math3.ode.FieldODEStateAndDerivative;
024
025/** This abstract class represents an interpolator over the last step
026 * during an ODE integration.
027 *
028 * <p>The various ODE integrators provide objects extending this class
029 * to the step handlers. The handlers can use these objects to
030 * retrieve the state vector at intermediate times between the
031 * previous and the current grid points (dense output).</p>
032 *
033 * @see org.apache.commons.math3.ode.FirstOrderFieldIntegrator
034 * @see StepHandler
035 *
036 * @param <T> the type of the field elements
037 * @since 3.6
038 */
039
040public abstract class AbstractFieldStepInterpolator<T extends RealFieldElement<T>>
041    implements FieldStepInterpolator<T> {
042
043    /** Global previous state. */
044    private final FieldODEStateAndDerivative<T> globalPreviousState;
045
046    /** Global current state. */
047    private final FieldODEStateAndDerivative<T> globalCurrentState;
048
049    /** Soft previous state. */
050    private final FieldODEStateAndDerivative<T> softPreviousState;
051
052    /** Soft current state. */
053    private final FieldODEStateAndDerivative<T> softCurrentState;
054
055    /** integration direction. */
056    private final boolean forward;
057
058    /** Mapper for ODE equations primary and secondary components. */
059    private FieldEquationsMapper<T> mapper;
060
061    /** Simple constructor.
062     * @param isForward integration direction indicator
063     * @param globalPreviousState start of the global step
064     * @param globalCurrentState end of the global step
065     * @param softPreviousState start of the restricted step
066     * @param softCurrentState end of the restricted step
067     * @param equationsMapper mapper for ODE equations primary and secondary components
068     */
069    protected AbstractFieldStepInterpolator(final boolean isForward,
070                                            final FieldODEStateAndDerivative<T> globalPreviousState,
071                                            final FieldODEStateAndDerivative<T> globalCurrentState,
072                                            final FieldODEStateAndDerivative<T> softPreviousState,
073                                            final FieldODEStateAndDerivative<T> softCurrentState,
074                                            final FieldEquationsMapper<T> equationsMapper) {
075        this.forward             = isForward;
076        this.globalPreviousState = globalPreviousState;
077        this.globalCurrentState  = globalCurrentState;
078        this.softPreviousState   = softPreviousState;
079        this.softCurrentState    = softCurrentState;
080        this.mapper              = equationsMapper;
081    }
082
083    /** Create a new restricted version of the instance.
084     * <p>
085     * The instance is not changed at all.
086     * </p>
087     * @param previousState start of the restricted step
088     * @param currentState end of the restricted step
089     * @return restricted version of the instance
090     * @see #getPreviousState()
091     * @see #getCurrentState()
092     */
093    public AbstractFieldStepInterpolator<T> restrictStep(final FieldODEStateAndDerivative<T> previousState,
094                                                         final FieldODEStateAndDerivative<T> currentState) {
095        return create(forward, globalPreviousState, globalCurrentState, previousState, currentState, mapper);
096    }
097
098    /** Create a new instance.
099     * @param newForward integration direction indicator
100     * @param newGlobalPreviousState start of the global step
101     * @param newGlobalCurrentState end of the global step
102     * @param newSoftPreviousState start of the restricted step
103     * @param newSoftCurrentState end of the restricted step
104     * @param newMapper equations mapper for the all equations
105     * @return a new instance
106     */
107    protected abstract AbstractFieldStepInterpolator<T> create(boolean newForward,
108                                                               FieldODEStateAndDerivative<T> newGlobalPreviousState,
109                                                               FieldODEStateAndDerivative<T> newGlobalCurrentState,
110                                                               FieldODEStateAndDerivative<T> newSoftPreviousState,
111                                                               FieldODEStateAndDerivative<T> newSoftCurrentState,
112                                                               FieldEquationsMapper<T> newMapper);
113
114    /**
115     * Get the previous global grid point state.
116     * @return previous global grid point state
117     */
118    public FieldODEStateAndDerivative<T> getGlobalPreviousState() {
119        return globalPreviousState;
120    }
121
122    /**
123     * Get the current global grid point state.
124     * @return current global grid point state
125     */
126    public FieldODEStateAndDerivative<T> getGlobalCurrentState() {
127        return globalCurrentState;
128    }
129
130    /** {@inheritDoc} */
131    public FieldODEStateAndDerivative<T> getPreviousState() {
132        return softPreviousState;
133    }
134
135    /** {@inheritDoc} */
136    public FieldODEStateAndDerivative<T> getCurrentState() {
137        return softCurrentState;
138    }
139
140    /** {@inheritDoc} */
141    public FieldODEStateAndDerivative<T> getInterpolatedState(final T time) {
142        final T thetaH         = time.subtract(globalPreviousState.getTime());
143        final T oneMinusThetaH = globalCurrentState.getTime().subtract(time);
144        final T theta          = thetaH.divide(globalCurrentState.getTime().subtract(globalPreviousState.getTime()));
145        return computeInterpolatedStateAndDerivatives(mapper, time, theta, thetaH, oneMinusThetaH);
146    }
147
148    /** {@inheritDoc} */
149    public boolean isForward() {
150        return forward;
151    }
152
153    /** Compute the state and derivatives at the interpolated time.
154     * This is the main processing method that should be implemented by
155     * the derived classes to perform the interpolation.
156     * @param equationsMapper mapper for ODE equations primary and secondary components
157     * @param time interpolation time
158     * @param theta normalized interpolation abscissa within the step
159     * (theta is zero at the previous time step and one at the current time step)
160     * @param thetaH time gap between the previous time and the interpolated time
161     * @param oneMinusThetaH time gap between the interpolated time and
162     * the current time
163     * @return interpolated state and derivatives
164     * @exception MaxCountExceededException if the number of functions evaluations is exceeded
165     */
166    protected abstract FieldODEStateAndDerivative<T> computeInterpolatedStateAndDerivatives(FieldEquationsMapper<T> equationsMapper,
167                                                                                            T time, T theta,
168                                                                                            T thetaH, T oneMinusThetaH)
169        throws MaxCountExceededException;
170
171}