Aproksymacja a konwersja DateTime do Double + inne kwestie

0

Witam :)

Kończę robić aproksymację, wedle wzoru, który przedstawił mi Dragon w tym temacie:
https://4programmers.net/Forum/Algorytmy/263894-aproksymacja_wielomianowa_funkcji_dyskretnej-_pomoc_w_zrozumieniu_koncepcji

Ale jest problem. Napisałem własną "bibliotekę" do obliczeń na macierzach- testowałem ją różnymi przykładami i działała fajnie, natomiast kiedy wprowadziłem do niej już właściwe dane, każda próba odpalenia tego samego kodu, kończy się jakimiś dzikimi wartościami.

Zdenerwowałem się, i zaprzęgłem do roboty bibliotekę Math.Numerics- była na I miejscu w liscie NuGetów. Zaimplementowałem... i to samo. Nie wiem naprawdę, co robić.

Wynikowa macierz ma rozmiar [liczbaWspółczynników x 1], więc niby pasuje jak ulał.
Skąd biorę dane?
Mam listę obiektów Pomiar.
W uproszczeniu- składa się on z pola double, który odpowiada wartości pomiaru, oraz obiektu DateTime, który przechowuje datę wykonania pomiaru. Daty są u mnie macierzą A a wartości są wektorem Y.

Wzór jest taki:
V=(ATA)-1*AT*Y

Mnożenie macierzy nie jest przemienne, więc "przygotowałem" sobie odpowiednie współczynniki po kolei (może nie potrzebnie).

Aproksymacja wygląda tak:

http://wklej.org/id/1909976/

Zwraca wielomian, który jest opisany tak:
http://wklej.org/id/1909981/

Problem może być taki, ze macierz ATA po odwróceniu, zawsze zawiera w większości NaN, zera albo jakieś małe wartości bliskie zeru. Kiedy inicjowałem testowe dane datami z właściwości DateTime.Now to czasem pojawiały się liczby, skrajnie różne- np - 20345.424324332, albo 34563.2342365426, albo 7.32423432 , albo tymi NaNami :)

Może te dane wejściowe nie są w porządku? Uciąć część ułamkową, przeskalować to jakoś? Nie widać nadziei, żeby to miało płynnie działać. :)

Tak wygląda testowe wywołanie tego wszystkiego. Stopień wielomianu chwilowo wprowadzam sobie ręcznie :)
http://wklej.org/id/1910466/

0

Kto macierz X nazywa A?! To jest przecież nieintuicyjne jak stosowanie przesunięcia bitowego zamiast dzielenia albo pisanie siedemnastu instrukcji w jednej linijce...

Jakie wartości masz w macierzy A i wektorze Y na wejśćiu?
Jak konwertujesz DateTime na liczbę?
Możliwe, że NaNy i inne dziwne liczby są efektem bardzo małych albo bardzo wielkich wartości w danych wejściowych. Prawdopodobnie należy je ustandaryzować przed rozpoczęciem obliczeń.
Być może lepiej też użyć typu decimal zamiast double do obliczeń. Ale dopóki nie podasz więcej informacji, to trudno coś konkretnego doradzić.
Nie wiem też, czy aproksymowanie regresją jest tutaj dobrym rozwiązaniem. Chcesz metodą prób i błędów sprawdzać różne wielomiany?

I najważniejsze - jakie wyniki dla tych samych danych, daje Matlab?

0

Dragon tak nazwał we wzorze, dla wygody w kodzie nazwałem ją X, ale komentarze opatrzyłem zgodnie ze wzorem, który podałem. :)
Wektor Y ma na wejściu takie wartości:
http://wklej.org/id/1910466/
Z właściwości Value tworzę wektor tych właściwości.

Jeśli o macierz X chodzi- Zamieniam obiekty DateTime za pomocą: https://msdn.microsoft.com/pl-pl/library/system.datetime.tooadate(v=vs.110).aspx i tworzę z nich macierz.

Na wejściu, w macierzy X są wartości rodzaju 45678.34534, a wektor Y to w tym wypadku [13.4 14.3 15 17 ... 67]T

Matlaba sprawdzę i dam znać.

0

Nie mam matlaba, a nie chcę jakichś kont zakładać, żeby dostać triala- użyłem scilaba.
Mój program wyliczył takie wartości https://dl.dropboxusercontent.com/u/64770159/Zrzut%20ekranu%202016-01-19%2010.33.35.png
Co czwarty indeks, zmienia się wiersz, w powyższym.

SciLab wyliczył to jako:
https://dl.dropboxusercontent.com/u/64770159/Zrzut%20ekranu%202016-01-19%2010.40.39.png
I wyznacznik tego, o ile dobrze rozumiem output, jest równy zero.

Tylko... macierz X składa wierszy, które są takie same. Czy przemnożenie tego przez transpozycję samej siebie, nie będzie doprowadzać w każdym przypadku do tego samego?
Czy dobrze zbudowałem macierz X w ogóle?

0

Ale użyj prawdziwych danych, bo jak masz równe wiersze/kolumny czy tam inną liniową zależność, to wyznacznik zawsze wyjdzie 0.

0

Przekopiowałem dane z programu :)
Rozumiem to tak:

Mam określoną ilość punktów X, powiedzmy [1 2 3] oraz wektor Y = [1 3 4 5]T

Po podstawieniu do ogólnego wzoru, układ równań powinien wyglądać tak:

1a3 + 2a2 + 3a1 = 1
1
a3 + 2a2 + 3a1 = 3
1a3 + 2a2 + 3a1 = 4
1
a3 + 2a2 + 3a1 = 5

Czyli macierz X wygląda tak:

1 2 3
1 2 3
1 2 3

prawda? :)

EDIT Nieee, Boże. Przepraszam za nie przeczytanie ze zrozumieniem. :D Zaglądnąłem do tematu i macierz X ma inną postać zupełnie.

0

Wektor Y ma tyle elementów, ile wierszy ma macierz X. Wiersze macierzy X zawierają kolejne potęgi wartości zmiennej niezależnej x, począwszy od zerowej do stopnia wielomianu, który zakładasz. Ty szukasz wektora parametrów b, czyli dla wielomianu postaci: y = b0 + b1 * x + b2 * x2 chcesz wyznaczyć wartości: b0, b1, b2
Wzór:

0

Ok, mam wrażenie, że zastosowałem wszystko... no i lipa. Wartość wielomianu w znanym punkcie, nie jest nawet zbliżona do znanej wartości. Zastosowałem bibliotekę do obliczeń Math.Numerics.

Funkcja main: http://wklej.org/id/1918584/
Aproksymacja: http://wklej.org/id/1919213/
Zwracany wielomian: http://wklej.org/id/1918588/
Klasa dla pomiaru: http://wklej.org/id/1918590/

Podając wartość X taką, dla której znam wartość (widać to w funkcji main) dostaję wynik: -109994789,287912 czyli trochę daleko...

Wynikowy wektor ma idealną długość, natomast wartości są kiepskie, bo zapisują się w postaci 10000,323232E+14, no różnie- ciężko z tego coś zrobić.
Nie wiem, co zrobić...

EDIT Poprawiłem zapisywanie do wspołczynników wielomianu w pliku z aproksymacją, indeks coś nie tegez był, ale i tak, dla 6 pomiarów, każdy ma wartość 10, wynik dla początkowej daty wynosi 50,7698747362997, a dla końcowej (kilka dni później), wynosi tyle : 50,7698747362997

Testowe wywołanie tego wygląda tak:

http://wklej.org/id/1919219/

0

Nieśmiało podbiję- jakby ktoś miał ochotę popatrzeć, siedzę dzisiaj do rana i dłubię w temacie. Każda pomysł się przyda. :)

0

Czy licząc Scilabem jesteś w stanie wskazać miejsce, w którym wyniki w porównaniu z Twoim programem się rozjeżdżają?
A standaryzowałeś w końcu te wartości? Tu chyba daty skonwertowane do double psują najbardziej, bo to są bądź co bądź, ogromne liczby. Jakby od każdej daty odjąć DateTime.Now, mogłoby być lepiej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1