1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.analysis.function;
19
20 import org.apache.commons.math4.legacy.analysis.ParametricUnivariateFunction;
21 import org.apache.commons.math4.legacy.analysis.differentiation.DerivativeStructure;
22 import org.apache.commons.math4.legacy.analysis.differentiation.UnivariateDifferentiableFunction;
23 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
24 import org.apache.commons.math4.legacy.exception.NullArgumentException;
25 import org.apache.commons.math4.core.jdkmath.JdkMath;
26
27
28
29
30
31
32
33 public class HarmonicOscillator implements UnivariateDifferentiableFunction {
34
35 private final double amplitude;
36
37 private final double omega;
38
39 private final double phase;
40
41
42
43
44
45
46
47
48 public HarmonicOscillator(double amplitude,
49 double omega,
50 double phase) {
51 this.amplitude = amplitude;
52 this.omega = omega;
53 this.phase = phase;
54 }
55
56
57 @Override
58 public double value(double x) {
59 return value(omega * x + phase, amplitude);
60 }
61
62
63
64
65
66
67
68
69
70
71 public static class Parametric implements ParametricUnivariateFunction {
72
73
74
75
76
77
78
79
80
81
82 @Override
83 public double value(double x, double ... param)
84 throws NullArgumentException,
85 DimensionMismatchException {
86 validateParameters(param);
87 return HarmonicOscillator.value(x * param[1] + param[2], param[0]);
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 @Override
104 public double[] gradient(double x, double ... param)
105 throws NullArgumentException,
106 DimensionMismatchException {
107 validateParameters(param);
108
109 final double amplitude = param[0];
110 final double omega = param[1];
111 final double phase = param[2];
112
113 final double xTimesOmegaPlusPhase = omega * x + phase;
114 final double a = HarmonicOscillator.value(xTimesOmegaPlusPhase, 1);
115 final double p = -amplitude * JdkMath.sin(xTimesOmegaPlusPhase);
116 final double w = p * x;
117
118 return new double[] { a, w, p };
119 }
120
121
122
123
124
125
126
127
128
129
130
131 private void validateParameters(double[] param)
132 throws NullArgumentException,
133 DimensionMismatchException {
134 if (param == null) {
135 throw new NullArgumentException();
136 }
137 if (param.length != 3) {
138 throw new DimensionMismatchException(param.length, 3);
139 }
140 }
141 }
142
143
144
145
146
147
148 private static double value(double xTimesOmegaPlusPhase,
149 double amplitude) {
150 return amplitude * JdkMath.cos(xTimesOmegaPlusPhase);
151 }
152
153
154
155
156 @Override
157 public DerivativeStructure value(final DerivativeStructure t)
158 throws DimensionMismatchException {
159 final double x = t.getValue();
160 double[] f = new double[t.getOrder() + 1];
161
162 final double alpha = omega * x + phase;
163 f[0] = amplitude * JdkMath.cos(alpha);
164 if (f.length > 1) {
165 f[1] = -amplitude * omega * JdkMath.sin(alpha);
166 final double mo2 = - omega * omega;
167 for (int i = 2; i < f.length; ++i) {
168 f[i] = mo2 * f[i - 2];
169 }
170 }
171
172 return t.compose(f);
173 }
174 }