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    *      http://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  package org.apache.commons.math4.legacy.analysis.function;
19  
20  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21  import org.apache.commons.math4.legacy.analysis.differentiation.DerivativeStructure;
22  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23  import org.apache.commons.math4.legacy.exception.NullArgumentException;
24  import org.apache.commons.math4.core.jdkmath.JdkMath;
25  import org.apache.commons.numbers.core.Precision;
26  import org.junit.Assert;
27  import org.junit.Test;
28  
29  /**
30   * Test for class {@link HarmonicOscillator}.
31   */
32  public class HarmonicOscillatorTest {
33      private final double EPS = Math.ulp(1d);
34  
35      @Test
36      public void testSomeValues() {
37          final double a = -1.2;
38          final double w = 0.34;
39          final double p = 5.6;
40          final UnivariateFunction f = new HarmonicOscillator(a, w, p);
41  
42          final double d = 0.12345;
43          for (int i = 0; i < 10; i++) {
44              final double v = i * d;
45              Assert.assertEquals(a * JdkMath.cos(w * v + p), f.value(v), 0);
46          }
47      }
48  
49      @Test
50      public void testDerivative() {
51          final double a = -1.2;
52          final double w = 0.34;
53          final double p = 5.6;
54          final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
55  
56          for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
57              final double d = 0.12345;
58              for (int i = 0; i < 10; i++) {
59                  final double v = i * d;
60                  final DerivativeStructure h = f.value(new DerivativeStructure(1, maxOrder, 0, v));
61                  for (int k = 0; k <= maxOrder; ++k) {
62                      final double trigo;
63                      switch (k % 4) {
64                          case 0:
65                              trigo = +JdkMath.cos(w * v + p);
66                              break;
67                          case 1:
68                              trigo = -JdkMath.sin(w * v + p);
69                              break;
70                          case 2:
71                              trigo = -JdkMath.cos(w * v + p);
72                              break;
73                          default:
74                              trigo = +JdkMath.sin(w * v + p);
75                              break;
76                      }
77                      Assert.assertEquals(a * JdkMath.pow(w, k) * trigo,
78                                          h.getPartialDerivative(k),
79                                          Precision.EPSILON);
80                  }
81              }
82          }
83      }
84  
85      @Test(expected=NullArgumentException.class)
86      public void testParametricUsage1() {
87          final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
88          g.value(0, null);
89      }
90  
91      @Test(expected=DimensionMismatchException.class)
92      public void testParametricUsage2() {
93          final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
94          g.value(0, new double[] {0});
95      }
96  
97      @Test(expected=NullArgumentException.class)
98      public void testParametricUsage3() {
99          final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
100         g.gradient(0, null);
101     }
102 
103     @Test(expected=DimensionMismatchException.class)
104     public void testParametricUsage4() {
105         final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
106         g.gradient(0, new double[] {0});
107     }
108 
109     @Test
110     public void testParametricValue() {
111         final double amplitude = 2;
112         final double omega = 3;
113         final double phase = 4;
114         final HarmonicOscillator f = new HarmonicOscillator(amplitude, omega, phase);
115 
116         final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
117         Assert.assertEquals(f.value(-1), g.value(-1, new double[] {amplitude, omega, phase}), 0);
118         Assert.assertEquals(f.value(0), g.value(0, new double[] {amplitude, omega, phase}), 0);
119         Assert.assertEquals(f.value(2), g.value(2, new double[] {amplitude, omega, phase}), 0);
120     }
121 
122     @Test
123     public void testParametricGradient() {
124         final double amplitude = 2;
125         final double omega = 3;
126         final double phase = 4;
127         final HarmonicOscillator.Parametric f = new HarmonicOscillator.Parametric();
128 
129         final double x = 1;
130         final double[] grad = f.gradient(1, new double[] {amplitude, omega, phase});
131         final double xTimesOmegaPlusPhase = omega * x + phase;
132         final double a = JdkMath.cos(xTimesOmegaPlusPhase);
133         Assert.assertEquals(a, grad[0], EPS);
134         final double w = -amplitude * x * JdkMath.sin(xTimesOmegaPlusPhase);
135         Assert.assertEquals(w, grad[1], EPS);
136         final double p = -amplitude * JdkMath.sin(xTimesOmegaPlusPhase);
137         Assert.assertEquals(p, grad[2], EPS);
138     }
139 }