/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.math3.ode.nonstiff; import java.util.Arrays; import org.apache.commons.math3.RealFieldElement; import org.apache.commons.math3.linear.Array2DRowFieldMatrix; import org.apache.commons.math3.ode.FieldEquationsMapper; import org.apache.commons.math3.ode.FieldODEStateAndDerivative; import org.apache.commons.math3.ode.sampling.AbstractFieldStepInterpolator; import org.apache.commons.math3.util.MathArrays; /** * This class implements an interpolator for Adams integrators using Nordsieck representation. * *
This interpolator computes dense output around the current point.
* The interpolation equation is based on Taylor series formulas.
*
* @see AdamsBashforthFieldIntegrator
* @see AdamsMoultonFieldIntegrator
* @param Sometimes, the reference state is the same as globalPreviousState,
* sometimes it is the same as globalCurrentState, so we use a separate
* field to avoid any confusion.
* the type of the field elements
*/
public static > FieldODEStateAndDerivative taylor(final FieldODEStateAndDerivative reference,
final S time, final S stepSize,
final S[] scaled,
final Array2DRowFieldMatrix nordsieck) {
final S x = time.subtract(reference.getTime());
final S normalizedAbscissa = x.divide(stepSize);
S[] stateVariation = MathArrays.buildArray(time.getField(), scaled.length);
Arrays.fill(stateVariation, time.getField().getZero());
S[] estimatedDerivatives = MathArrays.buildArray(time.getField(), scaled.length);
Arrays.fill(estimatedDerivatives, time.getField().getZero());
// apply Taylor formula from high order to low order,
// for the sake of numerical accuracy
final S[][] nData = nordsieck.getDataRef();
for (int i = nData.length - 1; i >= 0; --i) {
final int order = i + 2;
final S[] nDataI = nData[i];
final S power = normalizedAbscissa.pow(order);
for (int j = 0; j < nDataI.length; ++j) {
final S d = nDataI[j].multiply(power);
stateVariation[j] = stateVariation[j].add(d);
estimatedDerivatives[j] = estimatedDerivatives[j].add(d.multiply(order));
}
}
S[] estimatedState = reference.getState();
for (int j = 0; j < stateVariation.length; ++j) {
stateVariation[j] = stateVariation[j].add(scaled[j].multiply(normalizedAbscissa));
estimatedState[j] = estimatedState[j].add(stateVariation[j]);
estimatedDerivatives[j] =
estimatedDerivatives[j].add(scaled[j].multiply(normalizedAbscissa)).divide(x);
}
return new FieldODEStateAndDerivative(time, estimatedState, estimatedDerivatives);
}
}