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 java.lang.reflect.Array;
21
22 import org.apache.commons.math4.legacy.core.Field;
23 import org.apache.commons.math4.legacy.core.RealFieldElement;
24 import org.apache.commons.math4.legacy.ode.events.Action;
25 import org.apache.commons.math4.legacy.ode.events.FieldEventHandler;
26 import org.apache.commons.math4.core.jdkmath.JdkMath;
27 import org.apache.commons.math4.legacy.core.MathArrays;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class TestFieldProblem4<T extends RealFieldElement<T>>
46 extends TestFieldProblemAbstract<T> {
47
48
49 private T a;
50
51
52
53
54 public TestFieldProblem4(Field<T> field) {
55 super(field);
56 a = convert(1.2);
57 T[] y0 = MathArrays.buildArray(field, 2);
58 y0[0] = a.sin();
59 y0[1] = a.cos();
60 setInitialConditions(convert(0.0), y0);
61 setFinalConditions(convert(15));
62 setErrorScale(convert(1.0, 0.0));
63 }
64
65 @Override
66 public FieldEventHandler<T>[] getEventsHandlers() {
67 @SuppressWarnings("unchecked")
68 FieldEventHandler<T>[] handlers =
69 (FieldEventHandler<T>[]) Array.newInstance(FieldEventHandler.class, 2);
70 handlers[0] = new Bounce<>();
71 handlers[1] = new Stop<>();
72 return handlers;
73 }
74
75
76
77
78
79 @Override
80 public T[] getTheoreticalEventsTimes() {
81 T[] array = MathArrays.buildArray(getField(), 5);
82 array[0] = a.negate().add(1 * JdkMath.PI);
83 array[1] = a.negate().add(2 * JdkMath.PI);
84 array[2] = a.negate().add(3 * JdkMath.PI);
85 array[3] = a.negate().add(4 * JdkMath.PI);
86 array[4] = convert(120.0);
87 return array;
88 }
89
90 @Override
91 public T[] doComputeDerivatives(T t, T[] y) {
92 final T[] yDot = MathArrays.buildArray(getField(), getDimension());
93 yDot[0] = y[1];
94 yDot[1] = y[0].negate();
95 return yDot;
96 }
97
98 @Override
99 public T[] computeTheoreticalState(T t) {
100 T sin = t.add(a).sin();
101 T cos = t.add(a).cos();
102 final T[] y = MathArrays.buildArray(getField(), getDimension());
103 y[0] = sin.abs();
104 y[1] = (sin.getReal() >= 0) ? cos : cos.negate();
105 return y;
106 }
107
108 private static final class Bounce<T extends RealFieldElement<T>> implements FieldEventHandler<T> {
109
110 private int sign;
111
112 Bounce() {
113 sign = +1;
114 }
115
116 @Override
117 public void init(FieldODEStateAndDerivative<T> state0, T t) {
118 }
119
120 @Override
121 public T g(FieldODEStateAndDerivative<T> state) {
122 return state.getState()[0].multiply(sign);
123 }
124
125 @Override
126 public Action eventOccurred(FieldODEStateAndDerivative<T> state, boolean increasing) {
127
128 sign = -sign;
129 return Action.RESET_STATE;
130 }
131
132 @Override
133 public FieldODEState<T> resetState(FieldODEStateAndDerivative<T> state) {
134 T[] y = state.getState();
135 y[0] = y[0].negate();
136 y[1] = y[1].negate();
137 return new FieldODEState<>(state.getTime(), y);
138 }
139 }
140
141 private static final class Stop<T extends RealFieldElement<T>> implements FieldEventHandler<T> {
142
143 Stop() {
144 }
145
146 @Override
147 public void init(FieldODEStateAndDerivative<T> state0, T t) {
148 }
149
150 @Override
151 public T g(FieldODEStateAndDerivative<T> state) {
152 return state.getTime().subtract(12.0);
153 }
154
155 @Override
156 public Action eventOccurred(FieldODEStateAndDerivative<T> state, boolean increasing) {
157 return Action.STOP;
158 }
159
160 @Override
161 public FieldODEState<T> resetState(FieldODEStateAndDerivative<T> state) {
162 return state;
163 }
164 }
165 }