スライス、ベクトル化された操作、要素ごとのコンテンツの加算と減算などをサポートするNumPyのような配列を持つC ++(またはC)ライブラリはありますか?
スライス、ベクトル化された操作、要素ごとのコンテンツの加算と減算などをサポートするNumPyのような配列を持つC ++(またはC)ライブラリはありますか?
回答:
ここにあなたのニーズに合うかもしれないいくつかのフリーソフトウェアがあります。
GNU科学ライブラリは、このようにC言語で書かれたGPLソフトウェアです、それはCのようなプログラミング(ポインタなど)の割り当てと方法を持っています。GSLwrapまだGSLを使用している間、あなたは、プログラミングのC ++方法を持つことができます。GSLにはBLAS実装がありますが、さらにパフォーマンスが必要な場合は、デフォルトのCBLASの代わりにATLASを使用できます。
ブースト/ uBLASのライブラリはC ++で書かれており、ブーストパッケージとして配布、BSLライブラリです。これは、BLAS標準を実装するC ++の方法です。uBLASにはいくつかの線形代数関数が付属しており、ATLASへの実験的な結合があります。
固有のMPL2ライセンス(バージョン3.1.1から開始)またはLGPL3 / GPL2(旧バージョン)の下で配布、C ++で書かれた線形代数ライブラリです。これはC ++のプログラミング方法ですが、他の2つよりも統合されています(より多くのアルゴリズムとデータ構造が利用可能です)。Eigenは、デファクトスタンダードのBLAS APIに準拠していませんが、上記のBLAS実装よりも高速であると主張しています。Eigenは、並列実装にあまり力を入れていないようです。
アルマジロは、C ++用のLGPL3ライブラリです。LAPACK(numpyが使用するライブラリ)のバインディングがあります。再帰的なテンプレートとテンプレートメタプログラミングを使用します。これは良い点です(他のライブラリもそれを行っているかどうかはわかりませんか?)。
xtensorは、BSDライセンスのC ++ライブラリです。NumPyと非常によく似たC ++ APIを提供します。チートシートについては、https://xtensor.readthedocs.io/en/latest/numpy.htmlを参照してください。
これらの選択肢は、データ構造と基本的な線形代数を取得したいだけの場合に非常に役立ちます。スタイル、ライセンス、またはsysadminの課題(LAPACKのような大きなライブラリのインストールは難しい場合があります)に関する好みに応じて、ニーズに最適なものを選択できます。
a[:4,::-1,:,19] = b[None,-5:,None]
またはa[a>5]=0
同様のものをサポートし、配列およびインデックス操作関数の膨大なセットを利用できます。いつか誰かがC ++用にそのようなものを作ってくれることを本当に望んでいます。
a.colRange(4,7).rowRange(4,8)
場合a[4:7,4,8]
)および条件マスク(のa.setTo(cv::Scalar(0), a>5)
場合a[a>5]=0
)
xtensorを試してみてください。(NumPyからXtensorへのチートシートを参照してください)。
xtensorは、多次元配列式を使用した数値解析を目的としたC ++ライブラリです。
xtensorは提供します
例
2次元配列を初期化し、その行の1つと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 ++でのdeCasteljauアルゴリズムの簡単な実装を次に示します。
#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開発者の1人です。
Eigenは優れた線形代数ライブラリです。
http://eigen.tuxfamily.org/index.php?title=Main_Page
ヘッダーのみのライブラリなので、インストールは非常に簡単です。十分に最適化されたコードを生成するためにテンプレートに依存しています。行列演算を自動的にベクトル化します。
また、たとえば2つの行列間の「要素ごとの乗算」などの係数に関する演算も完全にサポートします。それはあなたが必要なものですか?
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フロントエンド)を使用して、満足してください。
これは古い質問です。まだ答えたくなった。思考は多くの人、特にC ++でコーディングするpydevsに役立つかもしれません。
すでにpythonnumpyを使用している場合は、NumCppが最適です。構文は最小限であり、pynumpyと同様の関数またはメソッドがあります。
readmeドキュメントの比較部分も非常にクールです。
NumCpp
nc::NdArray<int> arr = {{4, 2}, {9, 4}, {5, 6}};
arr.reshape(5, 3);
arr.astype<double>();
画像処理やニューラルネットワークに多次元配列(numpyなど)を使用する場合は、 OpenCV
cv::Mat
の画像処理アルゴリズムと一緒に。行列演算のみに使用したい場合は、それぞれのopencvモジュールをコンパイルしてサイズを縮小し、OpenCVライブラリを小さくする必要があります。
cv::Mat
(行列)は、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]
一方でGLMOpenGLとGLSLで簡単に噛み合うように設計され、それはインターフェースの非常に直感的なセットとC ++のための唯一の数学ライブラリ完全に機能するヘッダです。
ベクトルと行列の型、およびそれらに対するさまざまな操作を宣言します。
2つの行列を乗算するのは、(M1 * M2)のように簡単です。2つのベクトル(V1-V2)を減算します。
ベクトルまたは行列に含まれる値へのアクセスも同様に簡単です。たとえば、vec3ベクトルを宣言した後、vector.xを使用して最初の要素にアクセスできます。見てみな。