2010-07-01 10 views
5

Poszukuję ogólnego zoptymalizowanego obiektu wyszukiwania, który przyjmuje funkcję f (x) i tworzy liniową aproksymację prostopadłą z konfigurowalnymi parametrami dla zakresu xi przedziałów populacji.Ogólna liniowa tablica wyszukiwania wieloczęściowego

Oczywiście nie jest trudno napisać, ale biorąc pod uwagę, że jest to przydatne w przypadku wielu kosztownych funkcji (trygonometr, wydajność, odległość), myślałem, że ogólny może już istnieć. Proszę daj mi znać.

Inną przydatną funkcją jest przekształcenie do postaci szeregowej/deserializację tabeli odnośników, ponieważ dokładna tabela o wartości 100 000 punktów + może zająć kilka minut.

+0

Skąd wiesz 100000 wystarczy? zbyt wiele? czy za mało? Będziesz musiał scharakteryzować funkcję, którą aproksujesz, i sprawić, aby implementacja działała dobrze dla tych cech. http://en.wikipedia.org/wiki/Approximation_theory – rwong

Odpowiedz

4

Nie wierzę, że cokolwiek istnieje w bibliotekach klas .NET bezpośrednio. Coś może istnieć w bibliotece stron trzecich (like C5 perhaps).

Tworzenie ogólnej wersji funkcji, która może akceptować zakresy, jest nieco trudne w języku C#, ponieważ nie istnieje typ unifikujący lub interfejs zapewniający operatory arytmetyczne. Jednak z jakiegoś kreatywności, to jest możliwe, by stworzyć coś:

// 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); 
    } 
} 

Klasa ta wstępnego wyliczenia zbiór wartości domen dla funkcji domainFunc całym zakresie [dolna, górna>. Używa wyszukiwania binarnego do wyszukiwania - kompromisu, który pozwala na użycie dowolnego porównywalnego typu - nie tylko wbudowanego w typy liczbowe. Funkcja rangeFunc umożliwia kontrolę przyrostu za pomocą kodu zewnętrznego. Więc tutaj jest liniowy odnośnika do Math.Sin całym zakresie [0, PI/2> z przyrostem 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)