¿Hay alguna biblioteca de C ++ (o C) que tenga matrices similares a NumPy con soporte para cortar, operaciones vectorizadas, sumar y restar contenido elemento por elemento, etc.?
¿Hay alguna biblioteca de C ++ (o C) que tenga matrices similares a NumPy con soporte para cortar, operaciones vectorizadas, sumar y restar contenido elemento por elemento, etc.?
Respuestas:
Aquí hay varios programas de software gratuitos que pueden satisfacer sus necesidades.
La Biblioteca Científica GNU es un software GPL escrito en C. Por lo tanto, tiene una asignación similar a C y una forma de programación (punteros, etc.). Con GSLwrap , puede tener una forma de programación C ++, mientras sigue usando GSL. GSL tiene una implementación BLAS , pero puede usar ATLAS en lugar del CBLAS predeterminado, si desea aún más actuaciones.
La biblioteca boost / uBLAS es una biblioteca BSL, escrita en C ++ y distribuida como un paquete boost. Es una forma C ++ de implementar el estándar BLAS. uBLAS viene con algunas funciones de álgebra lineal, y hay un enlace experimental a ATLAS .
eigen es una biblioteca de álgebra lineal escrita en C ++, distribuida bajo la licencia MPL2 (a partir de la versión 3.1.1) o LGPL3 / GPL2 (versiones anteriores). Es una forma de programación C ++, pero más integrada que las otras dos (hay más algoritmos y estructuras de datos disponibles). Eigen afirma ser más rápido que las implementaciones de BLAS anteriores, sin seguir la API BLAS estándar de facto. Eigen no parece esforzarse mucho en la implementación paralela.
Armadillo es una biblioteca LGPL3 para C ++. Tiene enlace para LAPACK (la biblioteca utilizada por numpy). Utiliza plantillas recursivas y metaprogramación de plantillas, lo cual es un buen punto (no sé si otras bibliotecas también lo están haciendo).
xtensor es una biblioteca de C ++ con licencia BSD. Ofrece una API de C ++ muy similar a la de NumPy. Consulte https://xtensor.readthedocs.io/en/latest/numpy.html para ver una hoja de trucos.
Estas alternativas son realmente buenas si solo desea obtener estructuras de datos y álgebra lineal básica. Dependiendo de su gusto por el estilo, la licencia o los desafíos del administrador de sistemas (instalar bibliotecas grandes como LAPACK puede ser difícil), puede elegir la que mejor se adapte a sus necesidades.
a[:4,::-1,:,19] = b[None,-5:,None]
o a[a>5]=0
y similares, además de tener un gran conjunto de funciones de manipulación de matrices e índices disponibles. Realmente espero que alguien haga algo así para C ++ algún día.
a.colRange(4,7).rowRange(4,8)
para a[4:7,4,8]
) y máscara de condición ( a.setTo(cv::Scalar(0), a>5)
para a[a>5]=0
)
Prueba xtensor . (Consulte la hoja de referencia de NumPy to Xtensor ).
xtensor es una biblioteca de C ++ destinada al análisis numérico con expresiones de matriz multidimensionales.
xtensor proporciona
Ejemplo
Inicialice una matriz 2-D y calcule la suma de una de sus filas y una matriz 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;
Salidas
{7, 11, 14}
Inicialice una matriz 1-D y modifíquela en su lugar.
#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;
Salidas
{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}
DyND está diseñado para ser, entre otras cosas, una biblioteca similar a NumPy para C ++. Cosas como la transmisión, los operadores aritméticos y la división funcionan bien. Por otro lado, todavía es muy experimental y muchas funciones aún no se han implementado.
Aquí hay una implementación simple del algoritmo de Casteljau en C ++ usando arreglos 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;
}
Escribí una publicación de blog hace un tiempo con más ejemplos y comparaciones en paralelo de la sintaxis de Fortran 90, DyND en C ++ y NumPy en Python.
Descargo de responsabilidad: soy uno de los desarrolladores actuales de DyND.
Eigen es una buena biblioteca de álgebra lineal.
http://eigen.tuxfamily.org/index.php?title=Main_Page
Es bastante fácil de instalar ya que es una biblioteca solo de encabezado. Se basa en una plantilla para generar un código bien optimizado. Vectoriza automáticamente las operaciones matriciales.
También es totalmente compatible con operaciones de coeficiente, como la "multiplicación por elemento" entre dos matrices, por ejemplo. ¿Es lo que necesitas?
Blitz ++ admite matrices con un número arbitrario de ejes, mientras que Armadillo solo admite hasta tres (vectores, matrices y cubos). Eigen solo admite vectores y matrices (no cubos). La desventaja es que Blitz ++ no tiene funciones de álgebra lineal más allá de las operaciones básicas de entrada y las contracciones tensoriales. El desarrollo parece haberse ralentizado hace bastante tiempo, pero tal vez sea solo porque la biblioteca hace lo que hace y no es necesario realizar muchos cambios.
xtensor es bueno, pero terminé escribiendo una mini biblioteca yo mismo como un proyecto de juguete con c ++ 20, mientras trataba de mantener la interfaz lo más simple posible. Aquí está: https://github.com/gbalduzz/NDArray
Código de ejemplo:
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]]
Todavía no proporciona operadores aritméticos sofisticados que colapsen múltiples operaciones juntas, pero puede transmitir lambdas arbitrarias a un conjunto de tensores con la misma forma, o usar operadores aritméticos evaluados de manera perezosa.
Déjeme saber qué piensa acerca de la interfaz y cómo se compara con las otras opciones, y si esto tiene alguna esperanza, qué tipo de operaciones le gustaría ver implementadas.
¡Licencia gratuita y sin dependencia!
Anexo: logré compilar y ejecutar correctamente xtensor, y el resultado es que mi biblioteca es significativamente más rápida al iterar sobre las vistas (2 a 3X)
VIGRA contiene una buena implementación de matriz N-dimensional:
http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html
Lo uso mucho y lo encuentro muy simple y efectivo. También es solo encabezado, por lo que es muy fácil de integrar en su entorno de desarrollo. Es lo más parecido que he encontrado al uso de NumPy en términos de su API.
El principal inconveniente es que no se usa tan ampliamente como los demás, por lo que no encontrará mucha ayuda en línea. Eso, y tiene un nombre extraño (¡intenta buscarlo!)
Utilice LibTorch (interfaz de PyTorch para C ++) y sea feliz.
Ésta es una vieja pregunta. Todavía tenía ganas de responder. El pensamiento podría ayudar a muchos, especialmente a la codificación pydevs en C ++.
Si ya ha trabajado con python numpy, NumCpp es una gran opción. Es minimalista en sintaxis y tiene funciones o métodos similares a py numpy.
La parte de comparación en el documento Léame también es muy, muy buena.
NumCpp
nc::NdArray<int> arr = {{4, 2}, {9, 4}, {5, 6}};
arr.reshape(5, 3);
arr.astype<double>();
Si desea usar una matriz multidimensional (como numpy) para el procesamiento de imágenes o la red neuronal, puede usar OpenCV
cv::Mat
junto con toneladas de algoritmos de procesamiento de imágenes. En caso de que solo quiera usarlo para operaciones matriciales SOLAMENTE, solo tiene que compilar los módulos opencv respectivos para reducir el tamaño y tener una pequeña biblioteca OpenCV.
cv::Mat
(Matriz) es una matriz n-dimensional que se puede utilizar para almacenar varios tipos de datos, como imágenes RGB, HSV o en escala de grises, vectores con valores reales o complejos, otras matrices, etc.
Un tapete contiene la siguiente información: width, height, type, channels, data, flags, datastart, dataend
y así sucesivamente.
Tiene varios métodos para la manipulación de matrices. Bono que puede crear luego en núcleos CUDA y también cv::cuda::GpuMat
.
Considere que quiero crear una matriz con 10 filas, 20 columnas, escriba 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
PRIMA:
Compile una biblioteca opencv pequeña y compacta para solo operaciones matriciales. Una de las formas es como se menciona en este artículo.
O
compile el código fuente de opencv usando el siguiente comando 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
Prueba este ejemplo:
#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;
}
Compile el código con el siguiente comando:
$ g++ -std=c++11 opencv_mat.cc -o opencv_mat `pkg-config --libs opencv` `pkg-config --cflags opencv`
Ejecute el ejecutable:
$ ./opencv_mat
OpenCV Version 3.4.2
My Mat :
[0, 0, 0, 0;
0, 0, 0, 0]
El GSL es genial, hace todo lo que pide y mucho más. Sin embargo, tiene la licencia GPL.
Si bien GLM está diseñado para combinarse fácilmente con OpenGL y GLSL, es una biblioteca matemática de encabezado completamente funcional para C ++ con un conjunto de interfaces muy intuitivo.
Declara tipos de vectores y matrices, así como varias operaciones sobre ellos.
Multiplicar dos matrices es tan simple como (M1 * M2). Restando dos vectores (V1-V2).
Acceder a los valores contenidos en vectores o matrices es igualmente sencillo. Después de declarar un vector vec3, por ejemplo, se puede acceder a su primer elemento con vector.x. Echale un vistazo.