슬라이싱, 벡터화 작업, 요소 별 콘텐츠 추가 및 빼기 등을 지원하는 NumPy와 유사한 배열을 가진 C ++ (또는 C) 라이브러리가 있습니까?
슬라이싱, 벡터화 작업, 요소 별 콘텐츠 추가 및 빼기 등을 지원하는 NumPy와 유사한 배열을 가진 C ++ (또는 C) 라이브러리가 있습니까?
답변:
다음은 귀하의 요구에 맞는 몇 가지 무료 소프트웨어입니다.
GNU 과학 라이브러리 따라서 C. 작성된 GPL 소프트웨어, 그것은 C 같은 프로그래밍 (포인터 등)의 할당 및 방법이있다. 으로 GSLwrap 여전히 GSL을 사용하는 동안, 당신은, 프로그램의 C ++ 방법이 있습니다. GSL에는 BLAS 구현이 있지만 더 많은 성능을 원한다면 기본 CBLAS 대신 ATLAS 를 사용할 수 있습니다 .
부스트 / uBLAS의 라이브러리는 BSL 라이브러리, C ++로 작성 부스트 패키지로 배포됩니다. BLAS 표준을 구현하는 C ++ 방식입니다. uBLAS에는 몇 가지 선형 대수 함수가 제공 되며 ATLAS에 대한 실험적 바인딩이 있습니다.
eigen 은 C ++로 작성된 선형 대수 라이브러리로 MPL2 라이선스 (버전 3.1.1부터 시작) 또는 LGPL3 / GPL2 (이전 버전)에 따라 배포됩니다. C ++ 프로그래밍 방식이지만 다른 두 가지 방식보다 더 통합되어 있습니다 (더 많은 알고리즘과 데이터 구조를 사용할 수 있음). Eigen 은 위의 BLAS 구현보다 빠르지 만 사실상의 표준 BLAS API를 따르지 않는다고 주장합니다 . Eigen은 병렬 구현에 많은 노력을 기울이지 않는 것 같습니다.
Armadillo 는 C ++ 용 LGPL3 라이브러리입니다. LAPACK (numpy에서 사용하는 라이브러리)에 대한 바인딩이 있습니다 . 재귀 템플릿과 템플릿 메타 프로그래밍을 사용합니다. 이것은 좋은 점입니다 (다른 라이브러리에서도이 작업을 수행하는지 모르겠습니까?).
xtensor 는 BSD 라이센스가있는 C ++ 라이브러리입니다. NumPy와 매우 유사한 C ++ API를 제공합니다. 치트 시트는 https://xtensor.readthedocs.io/en/latest/numpy.html 을 참조 하십시오 .
이러한 대안은 데이터 구조와 기본 선형 대수를 얻고 자 할 때 정말 좋습니다. 스타일, 라이선스 또는 시스템 관리자 문제에 대한 취향에 따라 (LAPACK과 같은 큰 라이브러리를 설치하는 것이 어려울 수 있음) 필요에 가장 적합한 것을 선택할 수 있습니다.
a[:4,::-1,:,19] = b[None,-5:,None]
하거나 a[a>5]=0
유사한 것을 지원할 뿐만 아니라 방대한 배열 및 인덱스 조작 기능을 사용할 수 있습니다. 언젠가는 누군가가 C ++를 위해 그렇게 만들길 정말 바랍니다.
a.colRange(4,7).rowRange(4,8)
for a[4:7,4,8]
) 및 조건 마스크 ( a.setTo(cv::Scalar(0), a>5)
for a[a>5]=0
)
xtensor를 사용해보십시오 . ( NumPy to Xtensor 치트 시트 참조 ).
xtensor는 다차원 배열 표현식을 사용한 수치 분석을위한 C ++ 라이브러리입니다.
xtensor는 제공합니다
예
2 차원 배열을 초기화하고 행 중 하나와 1 차원 배열의 합을 계산합니다.
#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;
출력
{7, 11, 14}
1 차원 배열을 초기화하고 제자리에서 모양을 변경합니다.
#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;
출력
{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}
DyND 는 무엇보다도 C ++ 용 NumPy와 유사한 라이브러리로 설계되었습니다. 방송, 산술 연산자, 슬라이싱과 같은 것들은 모두 잘 작동합니다. 다른 한편으로는 여전히 매우 실험적이고 다양한 기능은 아직 구현되지 않았습니다.
다음은 DyND 배열을 사용하여 C ++에서 de Casteljau 알고리즘의 간단한 구현입니다.
#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;
}
Fortran 90, C ++의 DyND 및 Python의 NumPy 구문에 대한 더 많은 예제와 나란히 비교 하는 블로그 게시물 을 조금 전에 작성했습니다 .
면책 조항 : 저는 현재 DyND 개발자 중 한 명입니다.
Eigen은 좋은 선형 대수 라이브러리입니다.
http://eigen.tuxfamily.org/index.php?title=Main_Page
헤더 전용 라이브러리이기 때문에 설치가 매우 쉽습니다. 잘 최적화 된 코드를 생성하기 위해 템플릿에 의존합니다. 매트릭스 연산을 자동으로 벡터화합니다.
또한 예를 들어 두 행렬 간의 "요소 별 곱셈"과 같은 계수 현명한 연산을 완벽하게 지원합니다. 그것은 당신이 필요로하는 것입니까?
xtensor는 좋지만 인터페이스를 최대한 단순하게 유지하면서 C ++ 20을 사용하여 장난감 프로젝트로 직접 미니 라이브러리를 작성했습니다. 여기 있습니다 : https://github.com/gbalduzz/NDArray
예제 코드 :
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]]
여러 연산을 함께 축소하는 멋진 산술 연산자를 제공하지는 않지만 임의의 람다를 동일한 모양의 텐서 집합으로 브로드 캐스트하거나 느리게 평가 된 산술 연산자를 사용할 수 있습니다.
인터페이스에 대해 어떻게 생각하고 다른 옵션과 어떻게 비교되는지 알려주세요. 희망이 있다면 어떤 종류의 작업이 구현되기를 바라는지 알려주세요.
무료 라이센스 및 종속성 없음!
부록 : xtensor를 제대로 컴파일하고 실행 한 결과 뷰를 반복 할 때 라이브러리가 훨씬 빨라졌습니다 (2 배에서 3 배까지).
VIGRA에는 좋은 N 차원 배열 구현이 포함되어 있습니다.
http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html
광범위하게 사용하고 있으며 매우 간단하고 효과적입니다. 또한 헤더 전용이므로 개발 환경에 매우 쉽게 통합 할 수 있습니다. API 측면에서 NumPy를 사용하는 것과 가장 가까운 것입니다.
가장 큰 단점은 다른 것만 큼 널리 사용되지 않기 때문에 온라인에서 많은 도움을 찾을 수 없다는 것입니다. 이름이 어색합니다 (검색해보세요!).
LibTorch (C ++ 용 PyTorch 프런트 엔드)를 사용하고 행복하세요.
이미지 처리 또는 신경망에 다차원 배열 (예 : numpy)을 사용하려면 OpenCV
cv::Mat
수많은 이미지 처리 알고리즘과 함께 사용할 수 있습니다 . 매트릭스 작업에만 사용하려는 경우 각 opencv 모듈을 컴파일하여 크기를 줄이고 작은 OpenCV 라이브러리를 가져야합니다.
cv::Mat
(Matrix)는 RGB, HSV 또는 회색조 이미지, 실수 또는 복소수 값이있는 벡터, 기타 행렬 등과 같은 다양한 유형의 데이터를 저장하는 데 사용할 수있는 n 차원 배열입니다.
매트에는 다음 정보가 포함 width, height, type, channels, data, flags, datastart, dataend
됩니다.
매트릭스 조작을위한 몇 가지 방법이 있습니다. 그런 다음 CUDA 코어와 cv::cuda::GpuMat
.
10 개의 행, 20 개의 열이있는 행렬을 만들고 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
보너스:
매트릭스 작업을 위해 작고 컴팩트 한 opencv 라이브러리를 컴파일합니다. 한 가지 방법은이 기사에서 언급 한 것과 같습니다.
또는
다음 cmake 명령을 사용하여 opencv 소스 코드를 컴파일하십시오.
$ 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
이 예를 시도하십시오.
#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;
}
다음 명령을 사용하여 코드를 컴파일하십시오.
$ g++ -std=c++11 opencv_mat.cc -o opencv_mat `pkg-config --libs opencv` `pkg-config --cflags opencv`
실행 파일을 실행하십시오.
$ ./opencv_mat
OpenCV Version 3.4.2
My Mat :
[0, 0, 0, 0;
0, 0, 0, 0]