View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.analysis.function;
24  
25  import org.hipparchus.analysis.UnivariateFunction;
26  import org.hipparchus.analysis.differentiation.DSFactory;
27  import org.hipparchus.analysis.differentiation.DerivativeStructure;
28  import org.hipparchus.exception.MathIllegalArgumentException;
29  import org.hipparchus.exception.NullArgumentException;
30  import org.hipparchus.util.FastMath;
31  import org.hipparchus.util.Precision;
32  import org.junit.Assert;
33  import org.junit.Test;
34  
35  /**
36   * Test for class {@link HarmonicOscillator}.
37   */
38  public class HarmonicOscillatorTest {
39      private final double EPS = Math.ulp(1d);
40  
41      @Test
42      public void testSomeValues() {
43          final double a = -1.2;
44          final double w = 0.34;
45          final double p = 5.6;
46          final UnivariateFunction f = new HarmonicOscillator(a, w, p);
47  
48          final double d = 0.12345;
49          for (int i = 0; i < 10; i++) {
50              final double v = i * d;
51              Assert.assertEquals(a * FastMath.cos(w * v + p), f.value(v), 0);
52          }
53      }
54  
55      @Test
56      public void testDerivative() {
57          final double a = -1.2;
58          final double w = 0.34;
59          final double p = 5.6;
60          final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
61  
62          for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
63              final DSFactory factory = new DSFactory(1, maxOrder);
64              final double d = 0.12345;
65              for (int i = 0; i < 10; i++) {
66                  final double v = i * d;
67                  final DerivativeStructure h = f.value(factory.variable(0, v));
68                  for (int k = 0; k <= maxOrder; ++k) {
69                      final double trigo;
70                      switch (k % 4) {
71                          case 0:
72                              trigo = +FastMath.cos(w * v + p);
73                              break;
74                          case 1:
75                              trigo = -FastMath.sin(w * v + p);
76                              break;
77                          case 2:
78                              trigo = -FastMath.cos(w * v + p);
79                              break;
80                          default:
81                              trigo = +FastMath.sin(w * v + p);
82                              break;
83                      }
84                      Assert.assertEquals(a * FastMath.pow(w, k) * trigo,
85                                          h.getPartialDerivative(k),
86                                          Precision.EPSILON);
87                  }
88              }
89          }
90      }
91  
92      @Test(expected=NullArgumentException.class)
93      public void testParametricUsage1() {
94          final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
95          g.value(0, null);
96      }
97  
98      @Test(expected=MathIllegalArgumentException.class)
99      public void testParametricUsage2() {
100         final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
101         g.value(0, new double[] {0});
102     }
103 
104     @Test(expected=NullArgumentException.class)
105     public void testParametricUsage3() {
106         final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
107         g.gradient(0, null);
108     }
109 
110     @Test(expected=MathIllegalArgumentException.class)
111     public void testParametricUsage4() {
112         final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
113         g.gradient(0, new double[] {0});
114     }
115 
116     @Test
117     public void testParametricValue() {
118         final double amplitude = 2;
119         final double omega = 3;
120         final double phase = 4;
121         final HarmonicOscillator f = new HarmonicOscillator(amplitude, omega, phase);
122 
123         final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
124         Assert.assertEquals(f.value(-1), g.value(-1, new double[] {amplitude, omega, phase}), 0);
125         Assert.assertEquals(f.value(0), g.value(0, new double[] {amplitude, omega, phase}), 0);
126         Assert.assertEquals(f.value(2), g.value(2, new double[] {amplitude, omega, phase}), 0);
127     }
128 
129     @Test
130     public void testParametricGradient() {
131         final double amplitude = 2;
132         final double omega = 3;
133         final double phase = 4;
134         final HarmonicOscillator.Parametric f = new HarmonicOscillator.Parametric();
135 
136         final double x = 1;
137         final double[] grad = f.gradient(1, new double[] {amplitude, omega, phase});
138         final double xTimesOmegaPlusPhase = omega * x + phase;
139         final double a = FastMath.cos(xTimesOmegaPlusPhase);
140         Assert.assertEquals(a, grad[0], EPS);
141         final double w = -amplitude * x * FastMath.sin(xTimesOmegaPlusPhase);
142         Assert.assertEquals(w, grad[1], EPS);
143         final double p = -amplitude * FastMath.sin(xTimesOmegaPlusPhase);
144         Assert.assertEquals(p, grad[2], EPS);
145     }
146 }