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