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