2010-07-01 22 views
5

我正在尋找一個通用優化的查找對象,它需要函數f(x)並創建一個線性分段逼近,其中x和範圍的配置參數爲可配置參數。通用線性分段查找表

顯然這不難寫,但鑑於它對於很多昂貴的函數(trig,yield,distance)有用,我認爲通用的函數可能已經存在。請告訴我。

另一個有用的功能是序列化/反序列化查找表,因爲精確的100,000點+表可能需要幾分鐘才能構建。

+0

你怎麼知道100,000就夠了嗎?太多了?還是太少?您需要描述您近似的功能,並使這些功能的實現順利進行。 http://en.wikipedia.org/wiki/Approximation_theory – rwong 2010-07-03 10:32:39

回答

4

我不相信直接在.NET類庫中存在任何東西。第三方庫中可能存在某些內容(like C5 perhaps)。

在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)