1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.ode;
19
20 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
21 import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
22 import org.apache.commons.math4.legacy.exception.NoBracketingException;
23 import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
24 import org.apache.commons.math4.legacy.ode.nonstiff.ClassicalRungeKuttaIntegrator;
25 import org.apache.commons.math4.core.jdkmath.JdkMath;
26 import org.junit.Assert;
27 import org.junit.Test;
28
29
30 public class FirstOrderConverterTest {
31
32 @Test
33 public void testDoubleDimension() {
34 for (int i = 1; i < 10; ++i) {
35 SecondOrderDifferentialEquations eqn2 = new Equations(i, 0.2);
36 FirstOrderConverter eqn1 = new FirstOrderConverter(eqn2);
37 Assert.assertEquals(eqn1.getDimension(), 2 * eqn2.getDimension());
38 }
39 }
40
41 @Test
42 public void testDecreasingSteps()
43 throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException {
44
45 double previousError = Double.NaN;
46 for (int i = 0; i < 10; ++i) {
47
48 double step = JdkMath.pow(2.0, -(i + 1));
49 double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, step)
50 - JdkMath.sin(4.0);
51 if (i > 0) {
52 Assert.assertTrue(JdkMath.abs(error) < JdkMath.abs(previousError));
53 }
54 previousError = error;
55 }
56 }
57
58 @Test
59 public void testSmallStep()
60 throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException {
61 double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 1.0e-4)
62 - JdkMath.sin(4.0);
63 Assert.assertTrue(JdkMath.abs(error) < 1.0e-10);
64 }
65
66 @Test
67 public void testBigStep()
68 throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException {
69 double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 0.5)
70 - JdkMath.sin(4.0);
71 Assert.assertTrue(JdkMath.abs(error) > 0.1);
72 }
73
74 private static final class Equations
75 implements SecondOrderDifferentialEquations {
76
77 private int n;
78
79 private double omega2;
80
81 Equations(int n, double omega) {
82 this.n = n;
83 omega2 = omega * omega;
84 }
85
86 @Override
87 public int getDimension() {
88 return n;
89 }
90
91 @Override
92 public void computeSecondDerivatives(double t, double[] y, double[] yDot,
93 double[] yDDot) {
94 for (int i = 0; i < n; ++i) {
95 yDDot[i] = -omega2 * y[i];
96 }
97 }
98 }
99
100 private double integrateWithSpecifiedStep(double omega,
101 double t0, double t,
102 double step) throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException {
103 double[] y0 = new double[2];
104 y0[0] = JdkMath.sin(omega * t0);
105 y0[1] = omega * JdkMath.cos(omega * t0);
106 ClassicalRungeKuttaIntegrator i = new ClassicalRungeKuttaIntegrator(step);
107 double[] y = new double[2];
108 i.integrate(new FirstOrderConverter(new Equations(1, omega)), t0, y0, t, y);
109 return y[0];
110 }
111 }