是否有类似NumPy的数组支持切片、向量化操作、元素逐个相加和相减等功能的C++(或C)库?
是否有类似NumPy的数组支持切片、向量化操作、元素逐个相加和相减等功能的C++(或C)库?
GNU Scientific Library是一款使用GPL协议编写的C语言软件。因此,它有类似于C语言的分配和编程方式(指针等)。通过GSLwrap,您可以拥有C++编程方式,同时仍然使用GSL。 GSL具有BLAS实现,但如果您想要更高的性能,则可以使用ATLAS代替默认的CBLAS。
boost/uBLAS库是一个BSL库,用C ++编写并作为boost软件包分发。这是实现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以获取速查表。
a[:4,::-1,:,19] = b[None,-5:,None]
或a[a>5]=0
等操作,同时拥有大量的数组和索引操作函数可用。我真切地希望有一天能为C++开发出类似的工具。 - amaureaa.colRange(4,7).rowRange(4,8)
表示 a[4:7,4,8]
) 和条件掩码 (a.setTo(cv::Scalar(0), a>5)
表示 a[a>5]=0
)。 - xaedes试用xtensor。(请查看NumPy转Xtensor备忘单)。
xtensor是一个C++库,用于多维数组表达式的数值分析。
xtensor提供了:
示例
初始化一个二维数组并计算其中一行和一个一维数组的总和。
#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}
初始化一个一维数组并在原地重塑它。
#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 旨在成为一个类似于NumPy的C++库,支持广播、算术运算和切片等功能。然而,它仍处于实验阶段,许多功能尚未实现。
以下是使用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开发人员之一。
使用LibTorch(C++的PyTorch前端)并感到高兴。
a.index({Slice(None, 4), Slice(None, None, -1), Slice(), 19}) = b.index({None, Slice(-5, None), None})
文档:https://pytorch.org/cppdocs/notes/tensor_indexing.html - Martin TrenkmannOpenCV
cv::Mat
以及大量的图像处理算法。如果您只想将其用于矩阵运算,则只需编译相应的opencv模块以减小大小并拥有小型的OpenCV库。
cv :: Mat
(Matrix)是一个n维数组,可用于存储各种类型的数据,例如RGB、HSV或灰度图像、具有实数或复数值的向量、其他矩阵等。width,height,type,channels,data,flags,datastart,dataend
等等。cv :: cuda :: GpuMat
。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
BONUS:
编译仅包含矩阵运算的精简版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]
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]]
http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html
我广泛使用它,发现它非常简单和有效。它也只有头文件,非常容易集成到您的开发环境中。就API而言,它是我遇到的最接近NumPy的东西。Blitz++ 支持任意数量维度的数组,而 Armadillo 只支持三个维度(向量、矩阵和立方体)。Eigen 只支持向量和矩阵(不支持立方体)。缺点是 Blitz++ 没有线性代数函数除了基本的逐元素运算和张量收缩。开发似乎已经相当长时间没有进展,但可能是因为该库已经实现其功能,不需要太多更改。
std::valarray
非常有帮助。它在标准库中,并支持对所有元素进行切片、算术操作以及两个valarrays之间的操作。 - Synck