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