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 org.apache.commons.math.ode.DerivativeException; 024 import org.apache.commons.math.ode.FirstOrderIntegrator; 025 import org.apache.commons.math.ode.IntegratorException; 026 import org.apache.commons.math.ode.TestProblem1; 027 import org.apache.commons.math.ode.TestProblem5; 028 import org.apache.commons.math.ode.TestProblem6; 029 import org.apache.commons.math.ode.TestProblemHandler; 030 import org.junit.Test; 031 032 public class AdamsBashforthIntegratorTest { 033 034 @Test(expected=IntegratorException.class) 035 public void dimensionCheck() throws DerivativeException, IntegratorException { 036 TestProblem1 pb = new TestProblem1(); 037 FirstOrderIntegrator integ = 038 new AdamsBashforthIntegrator(2, 0.0, 1.0, 1.0e-10, 1.0e-10); 039 integ.integrate(pb, 040 0.0, new double[pb.getDimension()+10], 041 1.0, new double[pb.getDimension()+10]); 042 } 043 044 @Test(expected=IntegratorException.class) 045 public void testMinStep() throws DerivativeException, IntegratorException { 046 047 TestProblem1 pb = new TestProblem1(); 048 double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); 049 double maxStep = pb.getFinalTime() - pb.getInitialTime(); 050 double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; 051 double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; 052 053 FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, minStep, maxStep, 054 vecAbsoluteTolerance, 055 vecRelativeTolerance); 056 TestProblemHandler handler = new TestProblemHandler(pb, integ); 057 integ.addStepHandler(handler); 058 integ.integrate(pb, 059 pb.getInitialTime(), pb.getInitialState(), 060 pb.getFinalTime(), new double[pb.getDimension()]); 061 062 } 063 064 @Test 065 public void testIncreasingTolerance() 066 throws DerivativeException, IntegratorException { 067 068 int previousCalls = Integer.MAX_VALUE; 069 for (int i = -12; i < -5; ++i) { 070 TestProblem1 pb = new TestProblem1(); 071 double minStep = 0; 072 double maxStep = pb.getFinalTime() - pb.getInitialTime(); 073 double scalAbsoluteTolerance = Math.pow(10.0, i); 074 double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; 075 076 FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, minStep, maxStep, 077 scalAbsoluteTolerance, 078 scalRelativeTolerance); 079 TestProblemHandler handler = new TestProblemHandler(pb, integ); 080 integ.addStepHandler(handler); 081 integ.integrate(pb, 082 pb.getInitialTime(), pb.getInitialState(), 083 pb.getFinalTime(), new double[pb.getDimension()]); 084 085 // the 31 and 36 factors are only valid for this test 086 // and has been obtained from trial and error 087 // there is no general relation between local and global errors 088 assertTrue(handler.getMaximalValueError() > (31.0 * scalAbsoluteTolerance)); 089 assertTrue(handler.getMaximalValueError() < (36.0 * scalAbsoluteTolerance)); 090 assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); 091 092 int calls = pb.getCalls(); 093 assertEquals(integ.getEvaluations(), calls); 094 assertTrue(calls <= previousCalls); 095 previousCalls = calls; 096 097 } 098 099 } 100 101 @Test(expected = DerivativeException.class) 102 public void exceedMaxEvaluations() throws DerivativeException, IntegratorException { 103 104 TestProblem1 pb = new TestProblem1(); 105 double range = pb.getFinalTime() - pb.getInitialTime(); 106 107 AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(2, 0, range, 1.0e-12, 1.0e-12); 108 TestProblemHandler handler = new TestProblemHandler(pb, integ); 109 integ.addStepHandler(handler); 110 integ.setMaxEvaluations(650); 111 integ.integrate(pb, 112 pb.getInitialTime(), pb.getInitialState(), 113 pb.getFinalTime(), new double[pb.getDimension()]); 114 115 } 116 117 @Test 118 public void backward() throws DerivativeException, IntegratorException { 119 120 TestProblem5 pb = new TestProblem5(); 121 double range = Math.abs(pb.getFinalTime() - pb.getInitialTime()); 122 123 FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, 0, range, 1.0e-12, 1.0e-12); 124 TestProblemHandler handler = new TestProblemHandler(pb, integ); 125 integ.addStepHandler(handler); 126 integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), 127 pb.getFinalTime(), new double[pb.getDimension()]); 128 129 assertTrue(handler.getLastError() < 1.0e-8); 130 assertTrue(handler.getMaximalValueError() < 1.0e-8); 131 assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); 132 assertEquals("Adams-Bashforth", integ.getName()); 133 } 134 135 @Test 136 public void polynomial() throws DerivativeException, IntegratorException { 137 TestProblem6 pb = new TestProblem6(); 138 double range = Math.abs(pb.getFinalTime() - pb.getInitialTime()); 139 140 for (int nSteps = 1; nSteps < 8; ++nSteps) { 141 AdamsBashforthIntegrator integ = 142 new AdamsBashforthIntegrator(nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-10, 1.0e-10); 143 TestProblemHandler handler = new TestProblemHandler(pb, integ); 144 integ.addStepHandler(handler); 145 integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), 146 pb.getFinalTime(), new double[pb.getDimension()]); 147 if (nSteps < 4) { 148 assertTrue(integ.getEvaluations() > 160); 149 } else { 150 assertTrue(integ.getEvaluations() < 80); 151 } 152 } 153 154 } 155 156 }