| /* |
| * 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.math4.legacy.ode; |
| |
| import org.apache.commons.math4.legacy.exception.DimensionMismatchException; |
| import org.apache.commons.math4.legacy.exception.MaxCountExceededException; |
| import org.apache.commons.math4.legacy.exception.NoBracketingException; |
| import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException; |
| import org.apache.commons.math4.legacy.ode.nonstiff.ClassicalRungeKuttaIntegrator; |
| import org.apache.commons.math4.core.jdkmath.JdkMath; |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| |
| public class FirstOrderConverterTest { |
| |
| @Test |
| public void testDoubleDimension() { |
| for (int i = 1; i < 10; ++i) { |
| SecondOrderDifferentialEquations eqn2 = new Equations(i, 0.2); |
| FirstOrderConverter eqn1 = new FirstOrderConverter(eqn2); |
| Assert.assertEquals(eqn1.getDimension(), 2 * eqn2.getDimension()); |
| } |
| } |
| |
| @Test |
| public void testDecreasingSteps() |
| throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { |
| |
| double previousError = Double.NaN; |
| for (int i = 0; i < 10; ++i) { |
| |
| double step = JdkMath.pow(2.0, -(i + 1)); |
| double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, step) |
| - JdkMath.sin(4.0); |
| if (i > 0) { |
| Assert.assertTrue(JdkMath.abs(error) < JdkMath.abs(previousError)); |
| } |
| previousError = error; |
| } |
| } |
| |
| @Test |
| public void testSmallStep() |
| throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { |
| double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 1.0e-4) |
| - JdkMath.sin(4.0); |
| Assert.assertTrue(JdkMath.abs(error) < 1.0e-10); |
| } |
| |
| @Test |
| public void testBigStep() |
| throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { |
| double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 0.5) |
| - JdkMath.sin(4.0); |
| Assert.assertTrue(JdkMath.abs(error) > 0.1); |
| } |
| |
| private static final class Equations |
| implements SecondOrderDifferentialEquations { |
| |
| private int n; |
| |
| private double omega2; |
| |
| Equations(int n, double omega) { |
| this.n = n; |
| omega2 = omega * omega; |
| } |
| |
| @Override |
| public int getDimension() { |
| return n; |
| } |
| |
| @Override |
| public void computeSecondDerivatives(double t, double[] y, double[] yDot, |
| double[] yDDot) { |
| for (int i = 0; i < n; ++i) { |
| yDDot[i] = -omega2 * y[i]; |
| } |
| } |
| } |
| |
| private double integrateWithSpecifiedStep(double omega, |
| double t0, double t, |
| double step) throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { |
| double[] y0 = new double[2]; |
| y0[0] = JdkMath.sin(omega * t0); |
| y0[1] = omega * JdkMath.cos(omega * t0); |
| ClassicalRungeKuttaIntegrator i = new ClassicalRungeKuttaIntegrator(step); |
| double[] y = new double[2]; |
| i.integrate(new FirstOrderConverter(new Equations(1, omega)), t0, y0, t, y); |
| return y[0]; |
| } |
| } |