View Javadoc
1   package org.djutils.math.functions;
2   
3   import java.util.SortedSet;
4   import java.util.function.Function;
5   
6   /**
7    * MathFunction interface.
8    * <p>
9    * Copyright (c) 2024-2025 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
10   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
11   * distributed under a three-clause BSD-style license, which can be found at
12   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
13   * </p>
14   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
15   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
16   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
17   */
18  public interface MathFunction extends Comparable<MathFunction>, Function<Double, Double>
19  {
20  
21      /**
22       * Returns the derivative of the data with respect to fractional length.
23       * @return derivative of this MathFunction
24       */
25      MathFunction getDerivative();
26  
27      /**
28       * Attempts to find a simplified version of this MathFunction (e.g. replace <code>1 - 5</code> by <code>-4</code>).
29       * @return <code>this</code>, or a simplified version thereof
30       */
31      default MathFunction simplify()
32      {
33          return this;
34      }
35  
36      /**
37       * Get the scale factor of this MathFunction.
38       * @return the scale factor of this MathFunction
39       */
40      default double getScale()
41      {
42          return 1.0;
43      }
44  
45      /**
46       * Incorporate a multiplication factor to this MathFunction.
47       * @param factor the factor to incorporate
48       * @return a new MathFunction that yields the same result as the original function multiplied by the <code>factor</code>
49       */
50      MathFunction scaleBy(double factor);
51  
52      /**
53       * Format a numerical value. If the value is integer, format it without decimal point. If the value is not integer, use a
54       * reasonable format.
55       * @param value the value to format
56       * @return the formatted value
57       */
58      default String printValue(final double value)
59      {
60          if (value <= Long.MAX_VALUE && value >= Long.MIN_VALUE && value == Math.ceil(value))
61          {
62              return String.format("%d", (long) value);
63          }
64          return "" + value;
65      }
66  
67      /**
68       * Compare chains for sorting.
69       * @param chain1 chain <code>MathFunction</code> of first <code>MathFunction</code> (may be <code>null</code>)
70       * @param chain2 chain <code>MathFunction</code> of second <code>MathFunction</code> (may be <code>null</code>)
71       * @return int <code>&lt; 0</code> when <code>chain1</code> sorts before <code>chain2</code>; <code>&gt; 0</code> when
72       *         <code>chain1</code> sorts after <code>chain2</code>; <code>0</code> when <code>chain1</code> is equal to
73       *         <code>chain2</code>
74       */
75      default int compareChains(final MathFunction chain1, final MathFunction chain2)
76      {
77          if (chain1 == null && chain2 != null)
78          {
79              return 1;
80          }
81          if (chain1 != null && chain2 == null)
82          {
83              return -1;
84          }
85          if (chain1 != null)
86          {
87              return chain1.compareTo(chain2);
88          }
89          return 0;
90      }
91  
92      /**
93       * Sorting priority of this type of MathFunction (low values shall sort before higher).
94       * @return sorting priority of this type of MathFunction
95       */
96      int sortPriority();
97  
98      /**
99       * Determine sorting order among instances of a particular sub type of <code>MathFunction</code>. The sorting order should
100      * sort <code>MathFunction</code>s that may be combined next to one another. Because <code>MathFunction</code>s are also
101      * used in <code>SortedSet</code>s, this comparator may return 0 <b>if and only if</b> this and other are entirely equal!
102      * @param other the other <code>MathFunction</code> that must be of the same type
103      * @return int; &lt; 0 when this sorts before other; &gt; 0 when this sorts after other; 0 when this and other are identical
104      */
105     int compareWithinSubType(MathFunction other);
106 
107     /**
108      * This MathFunction is added to another; try to replace both by a combined <code>MathFunction</code>.
109      * @param other the other <code>MathFunction</code>
110      * @return combined MathFunction, or null when the two could not be combined
111      */
112     default MathFunction mergeAdd(final MathFunction other)
113     {
114         return null;
115     }
116 
117     /**
118      * This MathFunction is multiplied by another; try to replace both by a combined MathFunction.
119      * @param other the other MathFunction
120      * @return combined MathFunction, or null when the two could not be combined
121      */
122     default MathFunction mergeMultiply(final MathFunction other)
123     {
124         return null;
125     }
126 
127     /**
128      * This MathFunction is divided by another; try to replace both by a combined MathFunction.
129      * @param other the other MathFunction
130      * @return combined MathFunction, or null when the two could not be combined
131      */
132     default MathFunction mergeDivide(final MathFunction other)
133     {
134         return null;
135     }
136 
137     @Override
138     default int compareTo(final MathFunction other)
139     {
140         int result = this.sortPriority() - other.sortPriority();
141         if (result == 0)
142         {
143             return compareWithinSubType(other);
144         }
145         return result;
146     }
147 
148     /**
149      * Report what is known about knots of this <code>MathFunction</code> in some <code>Interval</code>. The report does
150      * <b>not</b> take chained functions into account.
151      * @param interval the <code>Interval</code> on which knowledge of knots is requested
152      * @return summary of what is known about knots in the Interval
153      */
154     KnotReport getKnotReport(Interval<?> interval);
155 
156     /**
157      * Report all knots of this <code>MathFunction</code> in some <code>Interval</code>. Throws
158      * <code>IllegalStateException</code> when the number of knots in the <code>Interval</code> is not known, or infinite.
159      * @param interval the <code>Interval</code> over which the knots must be reported
160      * @return all the knots of this <code>MathFunction</code> in the requested <code>Interval</code>
161      * @throws UnsupportedOperationException when the number of knots cannot be returned in a set because it is not known, or
162      *             infinite
163      */
164     SortedSet<Double> getKnots(Interval<?> interval);
165 
166     /**
167      * Wrapper for one domain and function value pair.
168      * @param s double; value in the domain of the function
169      * @param t double; value of the function for <code>s</code>
170      */
171     record TupleSt(double s, double t)
172     {
173     }
174 
175 }