Jestem nowy w informatyce i nauczyłem się już podstawowych metod integracji, interpolacji, metod takich jak RK4, Numerov itp. Na c ++, ale ostatnio mój profesor poprosił mnie o nauczenie się, jak używać LAPACK do rozwiązywania problemów związanych z macierzami. Jak na przykład znajdowanie wartości własnych złożonej macierzy. Nigdy nie korzystałem z bibliotek stron trzecich i prawie zawsze piszę własne funkcje. Szukałem od kilku dni, ale nie znalazłem przyjaznego dla amatora przewodnika po lapacku. Wszystkie są napisane słowami, których nie rozumiem i nie wiem, dlaczego korzystanie z już napisanych funkcji powinno być tak skomplikowane. Są pełne słów takich jak zgeev, dtrsv itp. I jestem sfrustrowany. Chcę tylko zakodować coś takiego jak ten pseudo-kod:
#include <lapack:matrix>
int main(){
LapackComplexMatrix A(n,n);
for...
for...
cin>>A(i,j);
cout<<LapackEigenValues(A);
return 0;
}
Nie wiem, czy jestem głupi, czy amatorski. Ale znowu, to nie powinno być takie trudne, prawda? Nie wiem nawet, czy powinienem używać LAPACK lub LAPACK ++. (Piszę kody w c ++ i nie znam znajomości Python ani FORTRAN) i jak je zainstalować.
Odpowiedzi:
Nie zgadzam się z niektórymi innymi odpowiedziami i powiem, że uważam, że zastanawianie się, jak korzystać z LAPACK, jest ważne w dziedzinie informatyki naukowej.
Istnieje jednak duża krzywa uczenia się przy korzystaniu z LAPACK. Jest tak, ponieważ jest napisane na bardzo niskim poziomie. Wadą tego jest to, że wydaje się bardzo tajemnicze i nieprzyjemne dla zmysłów. Zaletą jest to, że interfejs jest jednoznaczny i zasadniczo nigdy się nie zmienia. Ponadto implementacje LAPACK, takie jak Intel Math Kernel Library, są naprawdę szybkie.
Na własne potrzeby mam własne klasy C ++ wyższego poziomu, które otaczają podprogramy LAPACK. Wiele bibliotek naukowych używa również LAPACK poniżej. Czasami łatwiej jest po prostu z nich korzystać, ale moim zdaniem zrozumienie narzędzia pod spodem ma dużą wartość. W tym celu podałem mały działający przykład napisany w C ++ przy użyciu LAPACK, aby zacząć. Działa to w Ubuntu, z
liblapack3
zainstalowanym pakietem i innymi niezbędnymi pakietami do budowania. Prawdopodobnie można go używać w większości dystrybucji Linuksa, ale instalacja LAPACK i łączenie z nim może się różnić.Oto plik
test_lapack.cpp
Można to zbudować za pomocą wiersza poleceń
Spowoduje to utworzenie pliku wykonywalnego o nazwie
test_lapack
. Skonfigurowałem to do odczytu w pliku wejściowym tekstu. Oto plik o nazwiematrix.txt
zawierający matrycę 3x3.Aby uruchomić program, po prostu wpisz
w wierszu polecenia, a wynik powinien być
Komentarze:
extern "C"
sekcję u góry i do której dodałem podkreśleniedgeev_
. Wynika to z faktu, że biblioteka została napisana i zbudowana w Fortranie, dlatego konieczne jest dopasowanie symboli podczas łączenia. Jest to zależne od kompilatora i systemu, więc jeśli używasz tego w systemie Windows, wszystko będzie musiało się zmienić.źródło
Zwykle powstrzymuję się od mówienia ludziom, co moim zdaniem powinni zrobić, zamiast odpowiadania na ich pytania, ale w tym przypadku zrobię wyjątek.
Lapack jest napisany w FORTRAN, a API jest bardzo podobne do FORTRAN. Lapack posiada C API, który sprawia, że interfejs jest nieco mniej bolesny, ale korzystanie z Lapacka z C ++ nigdy nie będzie przyjemne.
Alternatywnie istnieje biblioteka klas macierzy C ++ o nazwie Eigen, która ma wiele możliwości Lapacka, zapewnia wydajność obliczeniową porównywalną z lepszymi implementacjami Lapacka i jest bardzo wygodna w użyciu z C ++. W szczególności oto, w jaki sposób można napisać przykładowy kod za pomocą Eigen
Ten przykładowy problem wartości własnej jest przypadkiem testowym dla funkcji Lapacka
dgeev
. Możesz przeglądać kod FORTRAN i wyniki dla tego problemu dgeev i tworzyć własne porównania.źródło
operator,
! Nigdy tego nie widziałem w praktyce :-)operator,
przeciążenie jest bardziej interesujące / lepsze niż mogłoby się początkowo wydawać. Służy do inicjalizacji macierzy. Wpisy inicjujące macierz mogą być stałymi skalarnymi, ale mogą być również wcześniej zdefiniowanymi macierzami lub sub-macierzami. Bardzo podobny do MATLAB. Szkoda, że moja umiejętność programowania w C ++ nie była wystarczająco dobra, aby zaimplementować coś, co sam wyrafinowałem ;-)Oto kolejna odpowiedź w tym samym stylu co powyżej.
Powinieneś zajrzeć do biblioteki algebry liniowej Armadillo C ++ .
Plusy:
DGESV
mumbo-jumbo, tylkoX = solve( A, B )
(chociaż istnieje powód tych dziwnie wyglądających nazw funkcji LAPACK ...).Oto jak wyglądałby kod @ BillGreene w Armadillo:
źródło