Я не верю, что что-либо существует в библиотеках классов .NET напрямую. Что-то может существовать в сторонней библиотеке (, например, C5, возможно ).
Создание универсальной версии функции, которая может принимать диапазоны, немного сложно в C #, так как нет унифицирующего типа или интерфейса, который предоставляет арифметические операторы. Однако, с некоторой креативностью, возможно создать что-то:
// generic linear lookup class, supports any comparable type T
public class LinearLookup<T> where T : IComparable<T>
{
private readonly List<T> m_DomainValues = new List<T>();
public LinearLookup( Func<T,T> domainFunc, Func<T,T> rangeFunc,
T lowerBound, T upperBound )
{
m_DomainValues = Range( domainFunc, rangeFunc,
lowerBound, upperBound )
.ToList();
}
public T Lookup( T rangeValue )
{
// this could be improved for numeric types
var index = m_DomainValues.BinarySearch( rangeValue );
if( index < 0 )
index = (-index)-1;
return m_DomainValues[index];
}
private static IEnumerable<T> Range( Func<T,T> domainFunc,
Func<T,T> rangeFunc, T lower, T upper )
{
var rangeVal = lower;
do
{
yield return domainFunc( rangeVal );
rangeVal = rangeFunc( rangeVal );
} while( rangeVal.CompareTo( upper ) < 0 );
}
}
Этот класс будет предварительно вычислять набор значений домена для функции domainFunc
в диапазоне [нижний, верхний>. Для поиска используется двоичный поиск - компромисс, который позволяет использовать любой сопоставимый тип, а не только встроенные числовые типы. Функция rangeFunc
позволяет управлять приращением внешним кодом. Итак, вот линейный поиск для Math.Sin
в диапазоне [0, PI / 2> с шагом 0,01:
var sinLookup = new LinearLookup( Math.Sin, x => x + 0.01d, 0, Math.PI/2 );
var lookupPI4 = sinLookup[Math.PI/4]; // fetch the value sin(π/4)