Author: luc Date: Wed Mar 3 21:28:16 2010 New Revision: 918702 URL: http://svn.apache.org/viewvc?rev=918702&view=rev Log: Simplified names of ODE with Jacobians integration classes Added step handling for this feature
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java - copied, changed from r917667, commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegrator.java commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java - copied, changed from r917667, commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquations.java commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODEWithJacobians.java - copied, changed from r917667, commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquationsWithPartials.java commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java (with props) commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java (with props) commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/jacobians/ commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobiansTest.java - copied, changed from r917667, commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegratorTest.java Removed: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegrator.java commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquations.java commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquationsWithPartials.java commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegratorTest.java Copied: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java (from r917667, commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegrator.java) URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java?p2=commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java&p1=commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegrator.java&r1=917667&r2=918702&rev=918702&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegrator.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java Wed Mar 3 21:28:16 2010 @@ -15,11 +15,22 @@ * limitations under the License. */ -package org.apache.commons.math.ode; +package org.apache.commons.math.ode.jacobians; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; import org.apache.commons.math.MathRuntimeException; +import org.apache.commons.math.ode.DerivativeException; +import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +import org.apache.commons.math.ode.FirstOrderIntegrator; +import org.apache.commons.math.ode.IntegratorException; +import org.apache.commons.math.ode.sampling.StepHandler; +import org.apache.commons.math.ode.sampling.StepInterpolator; /** This class enhances a first order integrator for differential equations to * compute also partial derivatives of the solution with respect to initial state @@ -29,35 +40,35 @@ * added to form a new compound problem of higher dimension. If the original ODE * problem has dimension n and there are p parameters, the compound problem will * have dimension n × (1 + n + k).</p> - * @see ParameterizedFirstOrderDifferentialEquations - * @see ParameterizedFirstOrderDifferentialEquationsWithPartials + * @see ParameterizedODE + * @see ParameterizedODEWithJacobians * @version $Revision$ $Date$ * @since 2.1 */ -public class EnhancedFirstOrderIntegrator { +public class FirstOrderIntegratorWithJacobians { /** Underlying integrator for compound problem. */ private final FirstOrderIntegrator integrator; /** Raw equations to integrate. */ - private final ParameterizedFirstOrderDifferentialEquationsWithPartials ode; + private final ParameterizedODEWithJacobians ode; /** Build an enhanced integrator using internal differentiation to compute jacobians. * @param integrator underlying integrator to solve the compound problem * @param ode original problem (f in the equation y' = f(t, y)) * @param p parameters array (may be null if {...@link - * ParameterizedFirstOrderDifferentialEquations#getParametersDimension() + * ParameterizedODE#getParametersDimension() * getParametersDimension()} from original problem is zero) * @param hY step sizes to use for computing the jacobian df/dy, must have the * same dimension as the original problem * @param hP step sizes to use for computing the jacobian df/dp, must have the * same dimension as the original problem parameters dimension * @see #EnhancedFirstOrderIntegrator(FirstOrderIntegrator, - * ParameterizedFirstOrderDifferentialEquationsWithPartials) + * ParameterizedODEWithJacobians) */ - public EnhancedFirstOrderIntegrator(final FirstOrderIntegrator integrator, - final ParameterizedFirstOrderDifferentialEquations ode, - final double[] p, final double[] hY, final double[] hP) { + public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator, + final ParameterizedODE ode, + final double[] p, final double[] hY, final double[] hP) { checkDimension(ode.getDimension(), hY); checkDimension(ode.getParametersDimension(), p); checkDimension(ode.getParametersDimension(), hP); @@ -69,14 +80,65 @@ * @param integrator underlying integrator to solve the compound problem * @param ode original problem, which can compute the jacobians by itself * @see #EnhancedFirstOrderIntegrator(FirstOrderIntegrator, - * ParameterizedFirstOrderDifferentialEquations, double[], double[], double[]) + * ParameterizedODE, double[], double[], double[]) */ - public EnhancedFirstOrderIntegrator(final FirstOrderIntegrator integrator, - final ParameterizedFirstOrderDifferentialEquationsWithPartials ode) { + public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator, + final ParameterizedODEWithJacobians ode) { this.integrator = integrator; this.ode = ode; } + /** Add a step handler to this integrator. + * <p>The handler will be called by the integrator for each accepted + * step.</p> + * @param handler handler for the accepted steps + * @see #getStepHandlers() + * @see #clearStepHandlers() + */ + public void addStepHandler(StepHandlerWithJacobians handler) { + integrator.addStepHandler(new StepHandlerWrapper(handler)); + } + + /** Get all the step handlers that have been added to the integrator. + * @return an unmodifiable collection of the added events handlers + * @see #addStepHandler(StepHandlerWithJacobians) + * @see #clearStepHandlers() + */ + public Collection<StepHandlerWithJacobians> getStepHandlers() { + final Collection<StepHandlerWithJacobians> handlers = + new ArrayList<StepHandlerWithJacobians>(); + for (final StepHandler handler : integrator.getStepHandlers()) { + if (handler instanceof StepHandlerWrapper) { + handlers.add(((StepHandlerWrapper) handler).getHandler()); + } + } + return handlers; + } + + /** Remove all the step handlers that have been added to the integrator. + * @see #addStepHandler(StepHandlerWithJacobians) + * @see #getStepHandlers() + */ + public void clearStepHandlers() { + + // preserve the handlers we did not add ourselves + final Collection<StepHandler> otherHandlers = new ArrayList<StepHandler>(); + for (final StepHandler handler : integrator.getStepHandlers()) { + if (!(handler instanceof StepHandlerWrapper)) { + otherHandlers.add(handler); + } + } + + // clear all handlers + integrator.clearStepHandlers(); + + // put back the preserved handlers + for (final StepHandler handler : otherHandlers) { + integrator.addStepHandler(handler); + } + + } + /** Integrate the differential equations and the variational equations up to the given time. * <p>This method solves an Initial Value Problem (IVP) and also computes the derivatives * of the solution with respect to initial state and parameters. This can be used as @@ -237,10 +299,10 @@ /** Wrapper class to compute jacobians by finite differences for ODE which do not compute them themselves. */ private static class FiniteDifferencesWrapper - implements ParameterizedFirstOrderDifferentialEquationsWithPartials { + implements ParameterizedODEWithJacobians { /** Raw ODE without jacobians computation. */ - private final ParameterizedFirstOrderDifferentialEquations ode; + private final ParameterizedODE ode; /** Parameters array (may be null if parameters dimension from original problem is zero) */ private final double[] p; @@ -260,7 +322,7 @@ * @param hY step sizes to use for computing the jacobian df/dy * @param hP step sizes to use for computing the jacobian df/dp */ - public FiniteDifferencesWrapper(final ParameterizedFirstOrderDifferentialEquations ode, + public FiniteDifferencesWrapper(final ParameterizedODE ode, final double[] p, final double[] hY, final double[] hP) { this.ode = ode; this.p = p.clone(); @@ -322,4 +384,225 @@ } + /** Wrapper for step handlers. */ + private class StepHandlerWrapper implements StepHandler { + + /** Underlying step handler with jacobians. */ + private final StepHandlerWithJacobians handler; + + /** Simple constructor. + * @param handler underlying step handler with jacobians + */ + public StepHandlerWrapper(final StepHandlerWithJacobians handler) { + this.handler = handler; + } + + /** Get the underlying step handler with jacobians. + * @return underlying step handler with jacobians + */ + public StepHandlerWithJacobians getHandler() { + return handler; + } + + /** {...@inheritdoc} */ + public void handleStep(StepInterpolator interpolator, boolean isLast) + throws DerivativeException { + handler.handleStep(new StepInterpolatorWrapper(interpolator, + ode.getDimension(), + ode.getParametersDimension()), + isLast); + } + + /** {...@inheritdoc} */ + public boolean requiresDenseOutput() { + return handler.requiresDenseOutput(); + } + + /** {...@inheritdoc} */ + public void reset() { + handler.reset(); + } + + } + + /** Wrapper for step interpolators. */ + private static class StepInterpolatorWrapper + implements StepInterpolatorWithJacobians { + + /** Wrapped interpolator. */ + private StepInterpolator interpolator; + + /** State array. */ + private double[] y; + + /** State derivative array. */ + private double[] yDot; + + /** Jacobian with respect to initial state dy/dy0. */ + private double[][] dydy0; + + /** Jacobian with respect to parameters dy/dp. */ + private double[][] dydp; + + /** Simple constructor. + * @param interpolator wrapped interpolator + * @param n dimension of the original ODE + * @param k number of parameters + */ + public StepInterpolatorWrapper(final StepInterpolator interpolator, + final int n, final int k) { + this.interpolator = interpolator; + y = new double[n]; + yDot = new double[n]; + dydy0 = new double[n][n]; + dydp = new double[n][k]; + } + + /** {...@inheritdoc} */ + public void setInterpolatedTime(double time) { + interpolator.setInterpolatedTime(time); + } + + /** {...@inheritdoc} */ + public boolean isForward() { + return interpolator.isForward(); + } + + /** {...@inheritdoc} */ + public double getPreviousTime() { + return interpolator.getPreviousTime(); + } + + /** {...@inheritdoc} */ + public double getInterpolatedTime() { + return interpolator.getInterpolatedTime(); + } + + /** {...@inheritdoc} */ + public double[] getInterpolatedY() throws DerivativeException { + double[] extendedState = interpolator.getInterpolatedState(); + System.arraycopy(extendedState, 0, y, 0, y.length); + return y; + } + + /** {...@inheritdoc} */ + public double[][] getInterpolatedDyDy0() throws DerivativeException { + double[] extendedState = interpolator.getInterpolatedState(); + final int n = y.length; + int start = n; + for (int i = 0; i < n; ++i) { + System.arraycopy(extendedState, start, dydy0[i], 0, n); + start += n; + } + return dydy0; + } + + /** {...@inheritdoc} */ + public double[][] getInterpolatedDyDp() throws DerivativeException { + double[] extendedState = interpolator.getInterpolatedState(); + final int n = y.length; + final int k = dydp[0].length; + int start = n * (n + 1); + for (int i = 0; i < n; ++i) { + System.arraycopy(extendedState, start, dydp[i], 0, k); + start += k; + } + return dydp; + } + + /** {...@inheritdoc} */ + public double[] getInterpolatedYDot() throws DerivativeException { + double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); + System.arraycopy(extendedDerivatives, 0, yDot, 0, yDot.length); + return yDot; + } + + /** {...@inheritdoc} */ + public double[][] getInterpolatedDyDy0Dot() throws DerivativeException { + double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); + final int n = y.length; + int start = n; + for (int i = 0; i < n; ++i) { + System.arraycopy(extendedDerivatives, start, dydy0[i], 0, n); + start += n; + } + return dydy0; + } + + /** {...@inheritdoc} */ + public double[][] getInterpolatedDyDpDot() throws DerivativeException { + double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); + final int n = y.length; + final int k = dydp[0].length; + int start = n * (n + 1); + for (int i = 0; i < n; ++i) { + System.arraycopy(extendedDerivatives, start, dydp[i], 0, k); + start += k; + } + return dydp; + } + + /** {...@inheritdoc} */ + public double getCurrentTime() { + return interpolator.getCurrentTime(); + } + + /** {...@inheritdoc} */ + public StepInterpolatorWithJacobians copy() throws DerivativeException { + return new StepInterpolatorWrapper(interpolator.copy(), + y.length, dydy0[0].length); + } + + /** {...@inheritdoc} */ + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(interpolator); + final int n = y.length; + final int k = dydp[0].length; + out.writeInt(n); + out.writeInt(k); + for (int i = 0; i < n; ++i) { + out.writeDouble(y[i]); + } + for (int i = 0; i < n; ++i) { + out.writeDouble(yDot[i]); + } + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + out.writeDouble(dydy0[i][j]); + } + } + for (int i = 0; i < n; ++i) { + for (int j = 0; j < k; ++j) { + out.writeDouble(dydp[i][j]); + } + } + } + + /** {...@inheritdoc} */ + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + interpolator = (StepInterpolator) in.readObject(); + final int n = in.readInt(); + final int k = in.readInt(); + y = new double[n]; + dydy0 = new double[n][n]; + dydp = new double[n][k]; + for (int i = 0; i < n; ++i) { + y[i] = in.readDouble(); + } + for (int i = 0; i < n; ++i) { + yDot[i] = in.readDouble(); + } + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + dydy0[i][j] = in.readDouble(); + } + } + for (int i = 0; i < n; ++i) { + for (int j = 0; j < k; ++j) { + dydp[i][j] = in.readDouble(); + } + } + } + + } } Copied: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java (from r917667, commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquations.java) URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java?p2=commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java&p1=commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquations.java&r1=917667&r2=918702&rev=918702&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquations.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java Wed Mar 3 21:28:16 2010 @@ -15,19 +15,21 @@ * limitations under the License. */ -package org.apache.commons.math.ode; +package org.apache.commons.math.ode.jacobians; + +import org.apache.commons.math.ode.FirstOrderDifferentialEquations; /** This interface represents {...@link FirstOrderDifferentialEquations * first order differential equations} with parameters. * - * @see EnhancedFirstOrderIntegrator + * @see FirstOrderIntegratorWithJacobians * * @version $Revision$ $Date$ * @since 2.1 */ -public interface ParameterizedFirstOrderDifferentialEquations +public interface ParameterizedODE extends FirstOrderDifferentialEquations { /** Get the number of parameters. Copied: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODEWithJacobians.java (from r917667, commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquationsWithPartials.java) URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODEWithJacobians.java?p2=commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODEWithJacobians.java&p1=commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquationsWithPartials.java&r1=917667&r2=918702&rev=918702&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/ParameterizedFirstOrderDifferentialEquationsWithPartials.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODEWithJacobians.java Wed Mar 3 21:28:16 2010 @@ -15,20 +15,22 @@ * limitations under the License. */ -package org.apache.commons.math.ode; +package org.apache.commons.math.ode.jacobians; +import org.apache.commons.math.ode.DerivativeException; -/** This interface represents {...@link ParameterizedFirstOrderDifferentialEquations + +/** This interface represents {...@link ParameterizedODE * first order differential equations} with parameters and partial derivatives. * - * @see EnhancedFirstOrderIntegrator + * @see FirstOrderIntegratorWithJacobians * * @version $Revision$ $Date$ * @since 2.1 */ -public interface ParameterizedFirstOrderDifferentialEquationsWithPartials - extends ParameterizedFirstOrderDifferentialEquations { +public interface ParameterizedODEWithJacobians + extends ParameterizedODE { /** Compute the partial derivatives of ODE with respect to state. * @param t current value of the independent <I>time</I> variable Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java?rev=918702&view=auto ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java (added) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java Wed Mar 3 21:28:16 2010 @@ -0,0 +1,77 @@ +/* + * 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.math.ode.jacobians; + +import org.apache.commons.math.ode.DerivativeException; + +/** + * This interface represents a handler that should be called after + * each successful step. + * + * <p>The ODE integrators compute the evolution of the state vector at + * some grid points that depend on their own internal algorithm. Once + * they have found a new grid point (possibly after having computed + * several evaluation of the derivative at intermediate points), they + * provide it to objects implementing this interface. These objects + * typically either ignore the intermediate steps and wait for the + * last one, store the points in an ephemeris, or forward them to + * specialized processing or output methods.</p> + * + * @see FirstOrderIntegratorWithJacobians + * @see StepInterpolatorWithJacobians + * @version $Revision$ $Date$ + * @since 2.1 + */ + +public interface StepHandlerWithJacobians { + + /** Determines whether this handler needs dense output. + * <p>This method allows the integrator to avoid performing extra + * computation if the handler does not need dense output. If this + * method returns false, the integrator will call the {...@link + * #handleStep} method with a {...@link DummyStepInterpolator} rather + * than a custom interpolator.</p> + * @return true if the handler needs dense output + */ + boolean requiresDenseOutput(); + + /** Reset the step handler. + * Initialize the internal data as required before the first step is + * handled. + */ + void reset(); + + /** + * Handle the last accepted step + * @param interpolator interpolator for the last accepted step. For + * efficiency purposes, the various integrators reuse the same + * object on each call, so if the instance wants to keep it across + * all calls (for example to provide at the end of the integration a + * continuous model valid throughout the integration range, as the + * {...@link org.apache.commons.math.ode.ContinuousOutputModel + * ContinuousOutputModel} class does), it should build a local copy + * using the clone method of the interpolator and store this copy. + * Keeping only a reference to the interpolator and reusing it will + * result in unpredictable behavior (potentially crashing the application). + * @param isLast true if the step is the last one + * @throws DerivativeException this exception is propagated to the + * caller if the underlying user function triggers one + */ + void handleStep(StepInterpolatorWithJacobians interpolator, boolean isLast) throws DerivativeException; + +} Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java?rev=918702&view=auto ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java (added) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java Wed Mar 3 21:28:16 2010 @@ -0,0 +1,186 @@ +/* + * 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.math.ode.jacobians; + +import java.io.Externalizable; + +import org.apache.commons.math.ode.DerivativeException; + +/** This interface represents an interpolator over the last step + * during an ODE integration. + * + * <p>The various ODE integrators provide objects implementing this + * interface to the step handlers. These objects are often custom + * objects tightly bound to the integrator internal algorithms. The + * handlers can use these objects to retrieve the state vector at + * intermediate times between the previous and the current grid points + * (this feature is often called dense output).</p> + * <p>One important thing to note is that the step handlers may be so + * tightly bound to the integrators that they often share some internal + * state arrays. This imply that one should <em>never</em> use a direct + * reference to a step interpolator outside of the step handler, either + * for future use or for use in another thread. If such a need arise, the + * step interpolator <em>must</em> be copied using the dedicated + * {...@link #copy()} method. + * </p> + * + * @see FirstOrderIntegratorWithJacobians + * @see StepHandlerWithJacobians + * @version $Revision$ $Date$ + * @since 2.1 + */ + +public interface StepInterpolatorWithJacobians extends Externalizable { + + /** + * Get the previous grid point time. + * @return previous grid point time + */ + double getPreviousTime(); + + /** + * Get the current grid point time. + * @return current grid point time + */ + double getCurrentTime(); + + /** + * Get the time of the interpolated point. + * If {...@link #setInterpolatedTime} has not been called, it returns + * the current grid point time. + * @return interpolation point time + */ + double getInterpolatedTime(); + + /** + * Set the time of the interpolated point. + * <p>Setting the time outside of the current step is now allowed, but + * should be used with care since the accuracy of the interpolator will + * probably be very poor far from this step. This allowance has been + * added to simplify implementation of search algorithms near the + * step endpoints.</p> + * <p>Setting the time changes the instance internal state. If a + * specific state must be preserved, a copy of the instance must be + * created using {...@link #copy()}.</p> + * @param time time of the interpolated point + */ + void setInterpolatedTime(double time); + + /** + * Get the state vector of the interpolated point. + * <p>The returned vector is a reference to a reused array, so + * it should not be modified and it should be copied if it needs + * to be preserved across several calls.</p> + * @return state vector at time {...@link #getInterpolatedTime} + * @see #getInterpolatedYDot() + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + */ + double[] getInterpolatedY() throws DerivativeException; + + /** + * Get the partial derivatives of the state vector with respect to + * the initial state of the interpolated point. + * <p>The returned vector is a reference to a reused array, so + * it should not be modified and it should be copied if it needs + * to be preserved across several calls.</p> + * @return partial derivatives of the state vector with respect to + * the initial state at time {...@link #getInterpolatedTime} + * @see #getInterpolatedY() + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + */ + double[][] getInterpolatedDyDy0() throws DerivativeException; + + /** + * Get the partial derivatives of the state vector with respect to + * the ODE parameters of the interpolated point. + * <p>The returned vector is a reference to a reused array, so + * it should not be modified and it should be copied if it needs + * to be preserved across several calls.</p> + * @return partial derivatives of the state vector with respect to + * the ODE parameters at time {...@link #getInterpolatedTime} + * @see #getInterpolatedY() + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + */ + double[][] getInterpolatedDyDp() throws DerivativeException; + + /** + * Get the time derivatives of the state vector of the interpolated point. + * <p>The returned vector is a reference to a reused array, so + * it should not be modified and it should be copied if it needs + * to be preserved across several calls.</p> + * @return derivatives of the state vector at time {...@link #getInterpolatedTime} + * @see #getInterpolatedY() + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + */ + double[] getInterpolatedYDot() throws DerivativeException; + + /** + * Get the time derivatives of the jacobian of the state vector + * with respect to the initial state of the interpolated point. + * <p>The returned vector is a reference to a reused array, so + * it should not be modified and it should be copied if it needs + * to be preserved across several calls.</p> + * @return time derivatives of the jacobian of the state vector + * with respect to the initial state at time {...@link #getInterpolatedTime} + * @see #getInterpolatedY() + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + */ + double[][] getInterpolatedDyDy0Dot() throws DerivativeException; + + /** + * Get the time derivatives of the jacobian of the state vector + * with respect to the ODE parameters of the interpolated point. + * <p>The returned vector is a reference to a reused array, so + * it should not be modified and it should be copied if it needs + * to be preserved across several calls.</p> + * @return time derivatives of the jacobian of the state vector + * with respect to the ODE parameters at time {...@link #getInterpolatedTime} + * @see #getInterpolatedY() + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + */ + double[][] getInterpolatedDyDpDot() throws DerivativeException; + + /** Check if the natural integration direction is forward. + * <p>This method provides the integration direction as specified by + * the integrator itself, it avoid some nasty problems in + * degenerated cases like null steps due to cancellation at step + * initialization, step control or discrete events + * triggering.</p> + * @return true if the integration variable (time) increases during + * integration + */ + boolean isForward(); + + /** Copy the instance. + * <p>The copied instance is guaranteed to be independent from the + * original one. Both can be used with different settings for + * interpolated time without any side effect.</p> + * @return a deep copy of the instance, which can be used independently. + * @throws DerivativeException if this call induces an automatic + * step finalization that throws one + * @see #setInterpolatedTime(double) + */ + StepInterpolatorWithJacobians copy() throws DerivativeException; + +} Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Copied: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobiansTest.java (from r917667, commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegratorTest.java) URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobiansTest.java?p2=commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobiansTest.java&p1=commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegratorTest.java&r1=917667&r2=918702&rev=918702&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/EnhancedFirstOrderIntegratorTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobiansTest.java Wed Mar 3 21:28:16 2010 @@ -15,14 +15,19 @@ * limitations under the License. */ -package org.apache.commons.math.ode; +package org.apache.commons.math.ode.jacobians; +import org.apache.commons.math.ode.DerivativeException; +import org.apache.commons.math.ode.FirstOrderIntegrator; +import org.apache.commons.math.ode.IntegratorException; +import org.apache.commons.math.ode.jacobians.FirstOrderIntegratorWithJacobians; +import org.apache.commons.math.ode.jacobians.ParameterizedODEWithJacobians; import org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.junit.Assert; import org.junit.Test; -public class EnhancedFirstOrderIntegratorTest { +public class FirstOrderIntegratorWithJacobiansTest { @Test public void testLowAccuracyExternalDifferentiation() @@ -91,8 +96,8 @@ double[][] dZdZ0 = new double[2][2]; double[][] dZdP = new double[2][1]; double hY = 1.0e-12; - EnhancedFirstOrderIntegrator extInt = - new EnhancedFirstOrderIntegrator(integ, brusselator, new double[] { b }, + FirstOrderIntegratorWithJacobians extInt = + new FirstOrderIntegratorWithJacobians(integ, brusselator, new double[] { b }, new double[] { hY, hY }, new double[] { hP }); extInt.integrate(0, z, new double[][] { { 0.0 }, { 1.0 } }, 20.0, z, dZdZ0, dZdP); residuals0.addValue(dZdP[0][0] - brusselator.dYdP0()); @@ -117,8 +122,8 @@ double[] z = { 1.3, b }; double[][] dZdZ0 = new double[2][2]; double[][] dZdP = new double[2][1]; - EnhancedFirstOrderIntegrator extInt = - new EnhancedFirstOrderIntegrator(integ, brusselator); + FirstOrderIntegratorWithJacobians extInt = + new FirstOrderIntegratorWithJacobians(integ, brusselator); extInt.integrate(0, z, new double[][] { { 0.0 }, { 1.0 } }, 20.0, z, dZdZ0, dZdP); residuals0.addValue(dZdP[0][0] - brusselator.dYdP0()); residuals1.addValue(dZdP[1][0] - brusselator.dYdP1()); @@ -129,7 +134,7 @@ Assert.assertTrue(residuals1.getStandardDeviation() < 0.001); } - private static class Brusselator implements ParameterizedFirstOrderDifferentialEquationsWithPartials { + private static class Brusselator implements ParameterizedODEWithJacobians { private double b;