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>< 0</code> when <code>chain1</code> sorts before <code>chain2</code>; <code>> 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; < 0 when this sorts before other; > 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 }