104 votes

Des tableaux à la NumPy pour le C++ ?

Existe-t-il des librairies C++ (ou C) qui proposent des tableaux de type NumPy avec prise en charge du découpage en tranches, des opérations vectorielles, de l'ajout et de la soustraction de contenu élément par élément, etc.

75voto

nojhan Points 1042

Voici plusieurs logiciels gratuits qui peuvent répondre à vos besoins.

  1. En Bibliothèque scientifique de GNU est un logiciel sous licence GPL écrit en C. Ainsi, il possède une allocation et une façon de programmer (pointeurs, etc.) semblables à celles du C. Avec la GSLwrap Vous pouvez donc programmer en C++ tout en utilisant la GSL. GSL a un BLAS mais vous pouvez utiliser ATLAS au lieu du CBLAS par défaut, si vous voulez encore plus de performances.

  2. En boost/uBLAS est une bibliothèque BSL, écrite en C++ et distribuée sous forme de paquetage boost. C'est une manière C++ d'implémenter le standard BLAS. uBLAS est livré avec quelques fonctions d'algèbre linéaire, et il y a une fonction liaison expérimentale avec ATLAS .

  3. eigen est une bibliothèque d'algèbre linéaire écrite en C++, distribuée sous la licence MPL2 (à partir de la version 3.1.1) ou LGPL3/GPL2 (versions plus anciennes). Il s'agit d'une façon de programmer en C++, mais plus intégrée que les deux autres (plus d'algorithmes et de structures de données sont disponibles). Eigen prétend être plus rapide que les implémentations BLAS ci-dessus, tout en ne respectant pas l'API BLAS standard de facto. Eigen ne semble pas faire beaucoup d'efforts sur l'implémentation parallèle.

  4. Armadillo est une bibliothèque LGPL3 pour C++. Elle a une liaison pour LAPACK (la bibliothèque utilisée par numpy). Elle utilise des modèles récursifs et la méta-programmation de modèles, ce qui est un bon point (je ne sais pas si d'autres bibliothèques le font aussi ?).

  5. xtensor est une bibliothèque C++ sous licence BSD. Elle offre une API C++ très similaire à celle de NumPy. Voir https://xtensor.readthedocs.io/en/latest/numpy.html pour une antisèche.

Ces alternatives sont vraiment bonnes si vous voulez juste connaître les structures de données et l'algèbre linéaire de base. En fonction de vos goûts en matière de style, de licence ou de défis pour l'administrateur système (l'installation de grandes bibliothèques comme LAPACK peut être difficile), vous pouvez choisir celle qui répond le mieux à vos besoins.

64voto

Quant Points 855

Essayer xtensor . (Voir le Aide-mémoire NumPy vers Xtensor ).

xtensor est une bibliothèque C++ destinée à l'analyse numérique avec des expressions de tableaux multidimensionnels.

xtensor fournit

  • un système d'expression extensible permettant une diffusion de type numpy.
  • une API suivant les idiomes de la bibliothèque standard C++.
  • des outils pour manipuler les expressions de tableaux et s'appuyer sur xtensor.

Exemple

Initialiser un tableau 2-D et calculer la somme d'une de ses lignes et d'un tableau 1-D.

#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;

Sorties

{7, 11, 14}

Initialiser un tableau 1-D et le remodeler sur place.

#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;

Sorties

{{1, 2, 3},
 {4, 5, 6},
 {7, 8, 9}}

8voto

IanH Points 1587

DyND est conçu pour être, entre autres choses, une bibliothèque de type NumPy pour C++. Des choses comme la diffusion, les opérateurs arithmétiques et le découpage en tranches fonctionnent bien. D'un autre côté, c'est toujours très expérimental et de nombreuses fonctionnalités n'ont pas encore été mises en œuvre.

Voici une mise en œuvre simple de l'algorithme de Casteljau en C++ à l'aide de tableaux 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;
}

J'ai écrit un article de blog Il y a quelque temps, j'ai publié un article contenant d'autres exemples et des comparaisons côte à côte de la syntaxe de Fortran 90, de DyND en C++ et de NumPy en Python.

Avertissement : je suis l'un des développeurs actuels de DyND.

4voto

Utilisez LibTorch (interface PyTorch pour C++) et soyez heureux.

4voto

Milind Deore Points 1090

Si vous voulez utiliser un tableau multidimensionnel (comme numpy) pour le traitement d'images ou un réseau neuronal, vous pouvez utiliser OpenCV cv::Mat ainsi que des tonnes d'algorithmes de traitement d'images. Si vous souhaitez l'utiliser UNIQUEMENT pour les opérations matricielles, il vous suffit de compiler les modules opencv respectifs pour réduire la taille et disposer d'une minuscule bibliothèque OpenCV.

cv::Mat (Matrice) est un tableau à n dimensions qui peut être utilisé pour stocker différents types de données, comme des images RVB, HSV ou en niveaux de gris, des vecteurs avec des valeurs réelles ou complexes, d'autres matrices, etc.

Un Mat contient les informations suivantes : width, height, type, channels, data, flags, datastart, dataend et ainsi de suite.

Il dispose de plusieurs méthodes de manipulation de la matrice. En prime, vous pouvez créer alors sur des cœurs CUDA ainsi que des cv::cuda::GpuMat .

Considérons que je veux créer une matrice de 10 lignes, 20 colonnes, de type 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

BONUS :

Compiler opencv petit et compact pour les seules opérations matricielles. L'un des moyens est celui mentionné dans cet article.

OU

compiler le code source opencv en utilisant la commande cmake suivante :

$ 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

Essayez cet exemple :

 #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;
 }

Compilez le code avec la commande suivante :

$ g++ -std=c++11 opencv_mat.cc -o opencv_mat `pkg-config --libs opencv` `pkg-config --cflags opencv`

Exécutez l'exécutable :

$ ./opencv_mat

OpenCV Version 3.4.2
My Mat :
[0, 0, 0, 0;
 0, 0, 0, 0]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X