From 35af6fe1d2d5eb648a4d15a3aeaf630064bd7e77 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 25 Mar 2007 15:42:44 +0000 Subject: [PATCH] Provided a factory pattern for the integrators git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@522285 13f79535-47bb-0310-9956-ffa450edef68 --- .../math/ode/FirstOrderIntegratorFactory.java | 297 ++++++++++++++++++ .../ode/FirstOrderIntegratorFactoryImpl.java | 278 ++++++++++++++++ .../ode/GraggBulirschStoerIntegratorTest.java | 6 +- 3 files changed, 579 insertions(+), 2 deletions(-) create mode 100644 src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactory.java create mode 100644 src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactoryImpl.java diff --git a/src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactory.java b/src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactory.java new file mode 100644 index 000000000..1ed91945c --- /dev/null +++ b/src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactory.java @@ -0,0 +1,297 @@ +/* + * 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; + +import org.apache.commons.discovery.tools.DiscoverClass; + +/** + * Abstract factory class used to create {@link FirstOrderIntegrator} instances. + *

+ * Integrators implementing the following fixed stepsize algorithms are supported: + *

+ * Concrete factories extending this class also specify a default fixed stepsize integrator, + * instances of which are returned by newDefaultFixedStepsizeIntegrator. + *

+ *

+ * Integrators implementing the following adaptive stepsize algorithms are supported: + *

+ * Concrete factories extending this class also specify default adaptive stepsize integrators, + * instances of which are returned by the two newDefaultAdaptiveStepsizeIntegrator + * methods. + *

+ * Common usage:

+ * FirstOrderIntegratorFactory factory = FirstOrderIntegratorFactory.newInstance();
+ *
+ * // create a Dormand-Prince 8(5,3) integrator to use with some step control parameters
+ * AdaptiveStepsizeIntegrator integrator =
+ *   factory.newDormandPrince853Integrator(minStep, maxStep,
+ *                                         scalAbsoluteTolerance,
+ *                                         scalRelativeTolerance);
+ * 
+ * + * Jakarta Commons Discovery + * is used to determine the concrete factory returned by + * FirstOrderIntegratorFactory.newInstance(). The default is + * {@link FirstOrderIntegratorFactoryImpl} + * + * @version $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer., 29 nov. 2006) $ + */ +public abstract class FirstOrderIntegratorFactory { + + /** + * Default constructor. + */ + protected FirstOrderIntegratorFactory() { + } + + /** + * Create a new factory. + * @return a new factory + */ + public static FirstOrderIntegratorFactory newInstance() { + FirstOrderIntegratorFactory factory = null; + try { + DiscoverClass dc = new DiscoverClass(); + factory = (FirstOrderIntegratorFactory) dc.newInstance( + FirstOrderIntegratorFactory.class, + "org.apache.commons.math.analysis.FirstOrderIntegratorFactoryImpl"); + } catch(Throwable t) { + return new FirstOrderIntegratorFactoryImpl(); + } + return factory; + } + + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * The actual integrator returned is determined by the underlying factory. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public abstract FirstOrderIntegrator newDefaultFixedStepsizeIntegrator(double step); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The actual integrator returned is determined by the underlying factory. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newDefaultAdaptiveStepsizeIntegrator( + double minStep, double maxStep, + double scalAbsoluteTolerance, + double scalRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The actual integrator returned is determined by the underlying factory. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newDefaultAdaptiveStepsizeIntegrator( + double minStep, double maxStep, + double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance); + + /** + * Create a new {@link FirstOrderIntegrator}. + * The integrator is an implementation of the Euler method. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public abstract FirstOrderIntegrator newEulerIntegrator(double step); + + /** + * Create a new {@link FirstOrderIntegrator}. + * The integrator is an implementation of the midpoint method. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public abstract FirstOrderIntegrator newMidpointIntegrator(double step); + + /** + * Create a new {@link FirstOrderIntegrator}. + * The integrator is an implementation of the classical Runge-Kutta method. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public abstract FirstOrderIntegrator newClassicalRungeKuttaIntegrator(double step); + + /** + * Create a new {@link FirstOrderIntegrator}. + * The integrator is an implementation of the Gill method. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public abstract FirstOrderIntegrator newGillIntegrator(double step); + + /** + * Create a new {@link FirstOrderIntegrator}. + * The integrator is an implementation of the 3/8 method. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public abstract FirstOrderIntegrator newThreeEighthesIntegrator(double step); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Higham-Hall method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newHighamHall54Integrator( + double minStep, double maxStep, + double scalAbsoluteTolerance, + double scalRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Higham-Hall method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newHighamHall54Integrator( + double minStep, double maxStep, + double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Dormand-Prince 5(4) method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newDormandPrince54Integrator( + double minStep, double maxStep, + double scalAbsoluteTolerance, + double scalRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Dormand-Prince 5(4) method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newDormandPrince54Integrator( + double minStep, double maxStep, + double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Dormand-Prince 8(5,3) method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newDormandPrince853Integrator( + double minStep, double maxStep, + double scalAbsoluteTolerance, + double scalRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Dormand-Prince 8(5,3) method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newDormandPrince853Integrator( + double minStep, double maxStep, + double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Gragg-Burlisch-Stoer method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newGraggBulirschStoerIntegrator( + double minStep, double maxStep, + double scalAbsoluteTolerance, + double scalRelativeTolerance); + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * The integrator is an implementation of the Gragg-Burlisch-Stoer method. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public abstract AdaptiveStepsizeIntegrator newGraggBulirschStoerIntegrator( + double minStep, double maxStep, + double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance); + +} diff --git a/src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactoryImpl.java b/src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactoryImpl.java new file mode 100644 index 000000000..f51fb0df6 --- /dev/null +++ b/src/java/org/apache/commons/math/ode/FirstOrderIntegratorFactoryImpl.java @@ -0,0 +1,278 @@ +/* + * 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; + +/** + * Provide a default implementation for several functions useful to generic + * integrators. + * + * @version $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer., 29 nov. 2006) $ + */ +public class FirstOrderIntegratorFactoryImpl extends + FirstOrderIntegratorFactory { + + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * This factory buid a {@link ClassicalRungeKuttaIntegrator + * classical Runge-Kutta} integrator by default. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public FirstOrderIntegrator newDefaultFixedStepsizeIntegrator(double step) { + return newClassicalRungeKuttaIntegrator(step); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link DormandPrince853Integrator + * Dormand-Prince 8(5,3)} integrator by default. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newDefaultAdaptiveStepsizeIntegrator( + double minStep, double maxStep, double scalAbsoluteTolerance, + double scalRelativeTolerance) { + return newDormandPrince853Integrator(minStep, maxStep, + scalAbsoluteTolerance, scalRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link DormandPrince853Integrator + * Dormand-Prince 8(5,3)} integrator by default. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newDefaultAdaptiveStepsizeIntegrator( + double minStep, double maxStep, double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance) { + return newDormandPrince853Integrator(minStep, maxStep, + vecAbsoluteTolerance, vecRelativeTolerance); + } + + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * This factory buid a {@link EulerIntegrator Euler} integrator. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public FirstOrderIntegrator newEulerIntegrator(double step) { + return new EulerIntegrator(step); + } + + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * This factory buid a {@link MidpointIntegrator midpoint} integrator. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public FirstOrderIntegrator newMidpointIntegrator(double step) { + return new MidpointIntegrator(step); + } + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * This factory buid a {@link ClassicalRungeKuttaIntegrator + * classical Runge-Kutta} integrator. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + + public FirstOrderIntegrator newClassicalRungeKuttaIntegrator(double step) { + return new ClassicalRungeKuttaIntegrator(step); + } + + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * This factory buid a {@link GillIntegrator Gill} integrator. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public FirstOrderIntegrator newGillIntegrator(double step) { + return new GillIntegrator(step); + } + + /** + * Create a new fixed stepsize {@link FirstOrderIntegrator}. + * This factory buid a {@link ThreeEighthesIntegrator 3/8} integrator. + * @param step the fixed stepsize. + * @return the new fixed step integrator + */ + public FirstOrderIntegrator newThreeEighthesIntegrator(double step) { + return new ThreeEighthesIntegrator(step); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link HighamHall54Integrator Higham-Hall} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newHighamHall54Integrator(double minStep, + double maxStep, double scalAbsoluteTolerance, + double scalRelativeTolerance) { + return new HighamHall54Integrator(minStep, maxStep, + scalAbsoluteTolerance, scalRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link HighamHall54Integrator Higham-Hall} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newHighamHall54Integrator(double minStep, + double maxStep, double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance) { + return new HighamHall54Integrator(minStep, maxStep, + vecAbsoluteTolerance, vecRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link DormandPrince54Integrator + * Dormand-Prince 5(4)} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newDormandPrince54Integrator( + double minStep, double maxStep, double scalAbsoluteTolerance, + double scalRelativeTolerance) { + return new DormandPrince54Integrator(minStep, maxStep, + scalAbsoluteTolerance, scalRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link DormandPrince54Integrator + * Dormand-Prince 5(4)} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newDormandPrince54Integrator(double minStep, + double maxStep, double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance) { + return new DormandPrince54Integrator(minStep, maxStep, + vecAbsoluteTolerance, vecRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link DormandPrince853Integrator + * Dormand-Prince 8(5,3)} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newDormandPrince853Integrator( + double minStep, double maxStep, double scalAbsoluteTolerance, + double scalRelativeTolerance) { + return new DormandPrince853Integrator(minStep, maxStep, + scalAbsoluteTolerance, scalRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link DormandPrince853Integrator + * Dormand-Prince 8(5,3)} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newDormandPrince853Integrator( + double minStep, double maxStep, double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance) { + return new DormandPrince853Integrator(minStep, maxStep, + vecAbsoluteTolerance, vecRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link GraggBulirschStoerIntegrator + * Gragg-Bulirsch-Stoer} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param scalAbsoluteTolerance allowed absolute error + * @param scalRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newGraggBulirschStoerIntegrator( + double minStep, double maxStep, double scalAbsoluteTolerance, + double scalRelativeTolerance) { + return new GraggBulirschStoerIntegrator(minStep, maxStep, + scalAbsoluteTolerance, scalRelativeTolerance); + } + + /** + * Create a new {@link AdaptiveStepsizeIntegrator}. + * This factory buid a {@link GraggBulirschStoerIntegrator + * Gragg-Bulirsch-Stoer} integrator. + * @param minStep minimal step (must be positive even for backward + * integration), the last step can be smaller than this + * @param maxStep maximal step (must be positive even for backward + * integration) + * @param vecAbsoluteTolerance allowed absolute error + * @param vecRelativeTolerance allowed relative error + * @return the new adaptive stepsize integrator + */ + public AdaptiveStepsizeIntegrator newGraggBulirschStoerIntegrator( + double minStep, double maxStep, double[] vecAbsoluteTolerance, + double[] vecRelativeTolerance) { + return new GraggBulirschStoerIntegrator(minStep, maxStep, + vecAbsoluteTolerance, vecRelativeTolerance); + } + +} diff --git a/src/test/org/apache/commons/math/ode/GraggBulirschStoerIntegratorTest.java b/src/test/org/apache/commons/math/ode/GraggBulirschStoerIntegratorTest.java index 8dd0e32ee..c48fade94 100644 --- a/src/test/org/apache/commons/math/ode/GraggBulirschStoerIntegratorTest.java +++ b/src/test/org/apache/commons/math/ode/GraggBulirschStoerIntegratorTest.java @@ -37,8 +37,10 @@ public class GraggBulirschStoerIntegratorTest public void testDimensionCheck() { try { TestProblem1 pb = new TestProblem1(); - GraggBulirschStoerIntegrator integrator = - new GraggBulirschStoerIntegrator(0.0, 1.0, 1.0e-10, 1.0e-10); + FirstOrderIntegratorFactory factory = + FirstOrderIntegratorFactory.newInstance(); + AdaptiveStepsizeIntegrator integrator = + factory.newGraggBulirschStoerIntegrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]);