1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS 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  package org.orekit.utils;
18  
19  import org.hipparchus.util.FastMath;
20  import org.hipparchus.util.Precision;
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.Test;
23  import org.orekit.time.AbsoluteDate;
24  
25  public class DifferentiationTest {
26  
27      @Test
28      public void testScaleOne() {
29          // with this step, computation is exact in IEEE754
30          doTestScale(1.0, FastMath.pow(1.0, -3), Precision.SAFE_MIN);
31      }
32  
33      @Test
34      public void testScalePowerOfTwoStepRepresentableNumber() {
35          // with this step, computation is exact in IEEE754
36          doTestScale(FastMath.scalb(1.0, -10), FastMath.pow(1.0, -7), Precision.SAFE_MIN);
37      }
38  
39      @Test
40      public void testScalePowerOfTwoStepNonRepresentableNumber() {
41          // with this step, computation has numerical noise
42          doTestScale(FastMath.scalb(1.0, -10), 0.007, 1.7e-12);
43      }
44  
45      private void doTestScale(final double scale, final double step, final double tolerance) {
46          ParameterDriver   driver = new ParameterDriver("", -100.0, scale,
47                                                         Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
48          ParameterFunction f0     = (d,t) -> 3 * d.getValue(t) * d.getValue(t) - 2 * d.getValue(t);
49          ParameterFunction f1Diff = Differentiation.differentiate(f0, 4, step);
50          ParameterFunction f1Ref  = (d,t) -> 6 * d.getValue(t) - 2;
51  
52          for (double x = -3.0; x < 3.0; x += 0.125) {
53              driver.setValue(x);
54              Assertions.assertEquals(f1Ref.value(driver, new AbsoluteDate()), f1Diff.value(driver, new AbsoluteDate()), tolerance);
55          }
56  
57      }
58  
59  }
60