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
018 package org.apache.commons.math.ode.nonstiff;
019
020 import static org.junit.Assert.assertEquals;
021 import static org.junit.Assert.assertTrue;
022
023 import java.io.ByteArrayInputStream;
024 import java.io.ByteArrayOutputStream;
025 import java.io.IOException;
026 import java.io.ObjectInputStream;
027 import java.io.ObjectOutputStream;
028 import java.util.Random;
029
030 import org.apache.commons.math.ode.ContinuousOutputModel;
031 import org.apache.commons.math.ode.DerivativeException;
032 import org.apache.commons.math.ode.IntegratorException;
033 import org.apache.commons.math.ode.TestProblem3;
034 import org.apache.commons.math.ode.sampling.StepHandler;
035 import org.apache.commons.math.ode.sampling.StepInterpolator;
036 import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils;
037 import org.junit.Test;
038
039 public class GraggBulirschStoerStepInterpolatorTest {
040
041 @Test
042 public void derivativesConsistency()
043 throws DerivativeException, IntegratorException {
044 TestProblem3 pb = new TestProblem3(0.9);
045 double minStep = 0;
046 double maxStep = pb.getFinalTime() - pb.getInitialTime();
047 double absTolerance = 1.0e-8;
048 double relTolerance = 1.0e-8;
049
050 GraggBulirschStoerIntegrator integ =
051 new GraggBulirschStoerIntegrator(minStep, maxStep,
052 absTolerance, relTolerance);
053 StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-8);
054 }
055
056 @Test
057 public void serialization()
058 throws DerivativeException, IntegratorException,
059 IOException, ClassNotFoundException {
060
061 TestProblem3 pb = new TestProblem3(0.9);
062 double minStep = 0;
063 double maxStep = pb.getFinalTime() - pb.getInitialTime();
064 double absTolerance = 1.0e-8;
065 double relTolerance = 1.0e-8;
066
067 GraggBulirschStoerIntegrator integ =
068 new GraggBulirschStoerIntegrator(minStep, maxStep,
069 absTolerance, relTolerance);
070 integ.addStepHandler(new ContinuousOutputModel());
071 integ.integrate(pb,
072 pb.getInitialTime(), pb.getInitialState(),
073 pb.getFinalTime(), new double[pb.getDimension()]);
074
075 ByteArrayOutputStream bos = new ByteArrayOutputStream();
076 ObjectOutputStream oos = new ObjectOutputStream(bos);
077 for (StepHandler handler : integ.getStepHandlers()) {
078 oos.writeObject(handler);
079 }
080
081 assertTrue(bos.size () > 34000);
082 assertTrue(bos.size () < 35000);
083
084 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
085 ObjectInputStream ois = new ObjectInputStream(bis);
086 ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject();
087
088 Random random = new Random(347588535632l);
089 double maxError = 0.0;
090 for (int i = 0; i < 1000; ++i) {
091 double r = random.nextDouble();
092 double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
093 cm.setInterpolatedTime(time);
094 double[] interpolatedY = cm.getInterpolatedState ();
095 double[] theoreticalY = pb.computeTheoreticalState(time);
096 double dx = interpolatedY[0] - theoreticalY[0];
097 double dy = interpolatedY[1] - theoreticalY[1];
098 double error = dx * dx + dy * dy;
099 if (error > maxError) {
100 maxError = error;
101 }
102 }
103
104 assertTrue(maxError < 5.0e-11);
105
106 }
107
108 @Test
109 public void checklone()
110 throws DerivativeException, IntegratorException {
111 TestProblem3 pb = new TestProblem3(0.9);
112 double minStep = 0;
113 double maxStep = pb.getFinalTime() - pb.getInitialTime();
114 double scalAbsoluteTolerance = 1.0e-8;
115 double scalRelativeTolerance = scalAbsoluteTolerance;
116 GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep,
117 scalAbsoluteTolerance,
118 scalRelativeTolerance);
119 integ.addStepHandler(new StepHandler() {
120 public void handleStep(StepInterpolator interpolator, boolean isLast)
121 throws DerivativeException {
122 StepInterpolator cloned = interpolator.copy();
123 double tA = cloned.getPreviousTime();
124 double tB = cloned.getCurrentTime();
125 double halfStep = Math.abs(tB - tA) / 2;
126 assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12);
127 assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12);
128 for (int i = 0; i < 10; ++i) {
129 double t = (i * tB + (9 - i) * tA) / 9;
130 interpolator.setInterpolatedTime(t);
131 assertTrue(Math.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10));
132 cloned.setInterpolatedTime(t);
133 assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12);
134 double[] referenceState = interpolator.getInterpolatedState();
135 double[] cloneState = cloned.getInterpolatedState();
136 for (int j = 0; j < referenceState.length; ++j) {
137 assertEquals(referenceState[j], cloneState[j], 1.0e-12);
138 }
139 }
140 }
141 public boolean requiresDenseOutput() {
142 return true;
143 }
144 public void reset() {
145 }
146 });
147 integ.integrate(pb,
148 pb.getInitialTime(), pb.getInitialState(),
149 pb.getFinalTime(), new double[pb.getDimension()]);
150
151 }
152
153 }