Czy są jakieś biblioteki C ++ (lub C), które mają tablice podobne do NumPy z obsługą wycinania, operacji wektoryzacji, dodawania i odejmowania zawartości element po elemencie itp.?
c++
arrays
dynamic-arrays
Llamageddon
źródło
źródło
Odpowiedzi:
Oto kilka bezpłatnych programów, które mogą odpowiadać Twoim potrzebom.
GNU Scientific Library to oprogramowanie GPL napisany w C. Tak więc, ma C-jak przydzielania i sposobu programowania (wskaźniki, etc.). Dzięki GSLwrap możesz programować w języku C ++, nadal używając GSL. GSL ma implementację BLAS , ale możesz użyć ATLAS zamiast domyślnego CBLAS, jeśli chcesz uzyskać jeszcze więcej wydajności.
Biblioteka boost / uBLAS jest biblioteką BSL napisaną w C ++ i rozpowszechnianą jako pakiet boost. Jest to sposób implementacji standardu BLAS w C ++. uBLAS zawiera kilka funkcji algebry liniowej oraz istnieje eksperymentalne powiązanie z ATLAS .
eigen to biblioteka algebry liniowej napisana w C ++, rozpowszechniana na licencji MPL2 (począwszy od wersji 3.1.1) lub LGPL3 / GPL2 (starsze wersje). Jest to sposób programowania w C ++, ale bardziej zintegrowany niż dwa pozostałe (dostępnych jest więcej algorytmów i struktur danych). Eigen twierdzi, że jest szybszy niż powyższe implementacje BLAS, ale nie jest zgodny z de facto standardowym BLAS API. Wydaje się, że Eigen nie wkłada wiele wysiłku w równoległe wdrażanie.
Armadillo to biblioteka LGPL3 dla C ++. Posiada powiązanie z LAPACK (biblioteka używana przez numpy). Używa szablonów rekurencyjnych i metaprogramowania szablonów, co jest dobrym punktem (nie wiem, czy inne biblioteki też to robią?).
xtensor to biblioteka C ++ na licencji BSD. Oferuje API C ++ bardzo podobne do NumPy. Zobacz https://xtensor.readthedocs.io/en/latest/numpy.html, aby uzyskać ściągawkę.
Te alternatywy są naprawdę dobre, jeśli chcesz tylko uzyskać struktury danych i podstawową algebrę liniową. W zależności od gustu w kwestii stylu, licencji lub wyzwań administratora systemu (instalacja dużych bibliotek, takich jak LAPACK może być trudna), możesz wybrać tę, która najlepiej odpowiada Twoim potrzebom.
źródło
a[:4,::-1,:,19] = b[None,-5:,None]
luba[a>5]=0
i podobne, a także mają ogromny zestaw dostępnych funkcji manipulowania tablicami i indeksami. Naprawdę mam nadzieję, że ktoś kiedyś zrobi coś takiego dla C ++.a.colRange(4,7).rowRange(4,8)
fora[4:7,4,8]
) i maska warunków (a.setTo(cv::Scalar(0), a>5)
fora[a>5]=0
)Wypróbuj xtensor . (Zobacz ściągawkę NumPy to Xtensor ).
xtensor to biblioteka C ++ przeznaczona do analizy numerycznej z wielowymiarowymi wyrażeniami tablicowymi.
xtensor zapewnia
Przykład
Zainicjuj tablicę 2-w i oblicz sumę jednego z jej wierszy i tablicy 1-w.
#include <iostream> #include "xtensor/xarray.hpp" #include "xtensor/xio.hpp" xt::xarray<double> arr1 {{1.0, 2.0, 3.0}, {2.0, 5.0, 7.0}, {2.0, 5.0, 7.0}}; xt::xarray<double> arr2 {5.0, 6.0, 7.0}; xt::xarray<double> res = xt::view(arr1, 1) + arr2; std::cout << res;
Wyjścia
{7, 11, 14}
Zainicjuj tablicę 1-W i zmień jej kształt w miejscu.
#include <iostream> #include "xtensor/xarray.hpp" #include "xtensor/xio.hpp" xt::xarray<int> arr {1, 2, 3, 4, 5, 6, 7, 8, 9}; arr.reshape({3, 3}); std::cout << arr;
Wyjścia
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
źródło
DyND został zaprojektowany między innymi jako biblioteka podobna do NumPy dla C ++. Takie rzeczy jak nadawanie, operatory arytmetyczne i wycinanie działają dobrze. Z drugiej strony nadal jest bardzo eksperymentalny i wiele funkcji nie zostało jeszcze zaimplementowanych.
Oto prosta implementacja algorytmu de Casteljau w C ++ przy użyciu tablic DyND:
#include <iostream> #include <dynd/array.hpp> using namespace dynd; nd::array decasteljau(nd::array a, double t){ size_t e = a.get_dim_size(); for(size_t i=0; i < e-1; i++){ a = (1.-t) * a(irange()<(e-i-1)) + t * a(0<irange()); } return a; } int main(){ nd::array a = {1., 2., 2., -1.}; std::cout << decasteljau(a, .25) << std::endl; }
Niedawno napisałem post na blogu z większą ilością przykładów i porównaniami składni dla Fortran 90, DyND w C ++ i NumPy w Pythonie.
Zastrzeżenie: jestem jednym z obecnych programistów DyND.
źródło
Eigen to dobra biblioteka algebry liniowej.
http://eigen.tuxfamily.org/index.php?title=Main_Page
Jest dość łatwa do zainstalowania, ponieważ jest to biblioteka zawierająca tylko nagłówki. Opiera się na szablonie, aby wygenerować dobrze zoptymalizowany kod. Wektoryzuje automatycznie operacje macierzowe.
Obsługuje również w pełni operacje oparte na współczynnikach, takie jak na przykład mnożenie na element między dwiema macierzami. To jest to, czego potrzebujesz?
źródło
Blitz ++ obsługuje tablice z dowolną liczbą osi, podczas gdy Armadillo obsługuje tylko do trzech (wektory, macierze i kostki). Eigen obsługuje tylko wektory i macierze (nie kostki). Wadą jest to, że Blitz ++ nie ma funkcji algebry liniowej poza podstawowymi operacjami entrywise i skróceniami tensorowymi. Wydaje się, że rozwój zwolnił już jakiś czas temu, ale może to tylko dlatego, że biblioteka robi to, co robi i nie trzeba wprowadzać wielu zmian.
źródło
xtensor jest dobry, ale ostatecznie napisałem mini-bibliotekę jako projekt zabawki w języku c ++ 20, starając się jednocześnie maksymalnie uprościć interfejs. Oto on: https://github.com/gbalduzz/NDArray
Przykładowy kod:
using namespace nd; NDArray<int, 2> m(3, 3); // 3x3 matrix m = 2; // assign 2 to all m(-1, all) = 1; // assign 1 to the last row. auto tile = m(range{1, end}, range{1, end}); // 2x2 tile std::sort(tile.begin(), tile.end()); std::cout << m; // prints [[2, 2, 2], [2, 1, 1], [1, 2, 2]]
Nie zapewnia jeszcze wymyślnych operatorów arytmetycznych, które zwijają wiele operacji razem, alemożna rozgłaszać dowolne lambdy do zestawu tensorów o tym samym kształcie lub używać leniwie ocenianych operatorów arytmetycznych.Daj mi znać, co myślisz o interfejsie i jak wypada on w porównaniu z innymi opcjami, a jeśli ma to jakąkolwiek nadzieję, jakie operacje chciałbyś zobaczyć zaimplementowane.
Darmowa licencja i brak zależności!
Dodatek: Udało mi się poprawnie skompilować i uruchomić xtensor, w wyniku czego moja biblioteka jest znacznie szybsza podczas iteracji po widokach (2 do 3X)
źródło
VIGRA zawiera dobrą implementację tablicy N-wymiarowej:
http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html
Używam go intensywnie i uważam, że jest bardzo prosty i skuteczny. Jest to również tylko nagłówek, dzięki czemu jest bardzo łatwy do zintegrowania ze środowiskiem programistycznym. Jest to najbliższa rzecz, z jaką się spotkałem przy korzystaniu z NumPy, jeśli chodzi o jego API.
Głównym minusem jest to, że nie jest tak szeroko stosowany jak inne, więc nie znajdziesz zbyt wiele pomocy w Internecie. To i ma niezręczną nazwę (spróbuj go wyszukać!)
źródło
Użyj LibTorch (nakładka PyTorch dla C ++) i bądź szczęśliwy.
źródło
To jest stare pytanie. Nadal miałam ochotę odpowiedzieć. Myśl może pomóc wielu, zwłaszcza pidevs kodowanie w C ++.
Jeśli już pracowałeś z Pythonem numpy, NumCpp to świetny wybór. Jest minimalistyczny w składni i ma podobne funkcje lub metody jak py numpy.
Część porównawcza w dokumencie readme jest również bardzo fajna.
nc::NdArray<int> arr = {{4, 2}, {9, 4}, {5, 6}}; arr.reshape(5, 3); arr.astype<double>();
źródło
Eigen to biblioteka szablonów dla algebry liniowej (macierze, wektory…). Jest dostępny tylko w nagłówku i darmowy (LGPL).
źródło
Jeśli chcesz używać wielowymiarowej tablicy (takiej jak numpy) do przetwarzania obrazu lub sieci neuronowej, możesz użyć
OpenCV
cv::Mat
wraz z mnóstwem algorytmów przetwarzania obrazu. Jeśli chcesz go używać TYLKO do operacji na macierzach, wystarczy skompilować odpowiednie moduły opencv, aby zmniejszyć rozmiar i mieć małą bibliotekę OpenCV.cv::Mat
(Matryca) to n-wymiarowa tablica, która może być używana do przechowywania różnego rodzaju danych, takich jak obrazy RGB, HSV lub w skali szarości, wektory z wartościami rzeczywistymi lub złożonymi, inne macierze itp.Mata zawiera następujące informacje:
width, height, type, channels, data, flags, datastart, dataend
i tak dalej.Posiada kilka metod manipulacji macierzą. Bonus, który możesz następnie stworzyć na rdzeniach CUDA, a także
cv::cuda::GpuMat
.Rozważ, że chcę utworzyć macierz z 10 wierszami, 20 kolumnami, wpisz CV_32FC3:
int R = 10, C = 20; Mat m1; m1.create(R, C, CV_32FC3); //creates empty matrix Mat m2(cv::Size(R, C), CV_32FC3); // creates a matrix with R rows, C columns with data type T where R and C are integers, Mat m3(R, C, CV_32FC3); // same as m2
PREMIA:
Skompiluj małą i kompaktową bibliotekę opencv do wykonywania tylko operacji na macierzach. Jeden ze sposobów jest taki, jak wspomniano w tym artykule.
LUB
skompiluj kod źródłowy opencv za pomocą następującego polecenia cmake:
$ git clone https://github.com/opencv/opencv.git $ cd opencv $ git checkout <version you want to checkout> $ mkdir build $ cd build $ cmake -D WITH_CUDA=OFF -D WITH_MATLAB=OFF -D BUILD_ANDROID_EXAMPLES=OFF -D BUILD_DOCS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -DANDROID_STL=c++_shared -DBUILD_SHARED_LIBS=ON -D BUILD_opencv_objdetect=OFF -D BUILD_opencv_video=OFF -D BUILD_opencv_videoio=OFF -D BUILD_opencv_features2d=OFF -D BUILD_opencv_flann=OFF -D BUILD_opencv_highgui=OFF -D BUILD_opencv_ml=OFF -D BUILD_opencv_photo=OFF -D BUILD_opencv_python=OFF -D BUILD_opencv_shape=OFF -D BUILD_opencv_stitching=OFF -D BUILD_opencv_superres=OFF -D BUILD_opencv_ts=OFF -D BUILD_opencv_videostab=OFF -D BUILD_opencv_dnn=OFF -D BUILD_opencv_imgproc=OFF .. $ make -j $nproc $ sudo make install
Wypróbuj ten przykład:
#include "opencv2/core.hpp" #include<iostream> int main() { std::cout << "OpenCV Version " << CV_VERSION << std::endl; int R = 2, C = 4; cv::Mat m1; m1.create(R, C, CV_32FC1); //creates empty matrix std::cout << "My Mat : \n" << m1 << std::endl; }
Skompiluj kod za pomocą następującego polecenia:
$ g++ -std=c++11 opencv_mat.cc -o opencv_mat `pkg-config --libs opencv` `pkg-config --cflags opencv`
Uruchom plik wykonywalny:
$ ./opencv_mat OpenCV Version 3.4.2 My Mat : [0, 0, 0, 0; 0, 0, 0, 0]
źródło
GSL jest super, robi wszystko, co prosisz i wiele więcej. Jest jednak licencjonowany na licencji GPL.
źródło
Chociaż GLM został zaprojektowany tak, aby łatwo łączyć się z OpenGL i GLSL, jest to w pełni funkcjonalna biblioteka matematyczna dla C ++ tylko z nagłówkiem z bardzo intuicyjnym zestawem interfejsów.
Deklaruje typy wektorowe i macierzowe, a także różne operacje na nich.
Mnożenie dwóch macierzy jest proste jak (M1 * M2). Odejmowanie dwóch wektorów (V1-V2).
Dostęp do wartości zawartych w wektorach lub macierzach jest równie prosty. Na przykład po zadeklarowaniu wektora vec3 można uzyskać dostęp do jego pierwszego elementu za pomocą vector.x. Sprawdź to.
źródło