2012-06-23 20 views
41

¿Existen libs en C++ (o C) que tengan matrices similares a NumPy con soporte para cortar, operaciones vectorizadas, sumar y restar elementos elemento por elemento, etc.?matrices de estilo NumPy para C++?

+2

[Armadillo] (http://arma.sourceforge.net/)? –

+0

Por lo que sé numpy usa [LAPACK] (http://en.wikipedia.org/wiki/LAPACK). Mientras que está escrito en Fortran, hay enlaces de C++ disponibles. Aunque nunca usé ninguno de esos. – Voo

+0

Hay una interfaz C++ reciente para NumPy, llamada [ArmaNpy] (https://sourceforge.net/projects/armanpy/). – mtall

Respuesta

28

Aquí hay varios programas gratuitos que pueden adaptarse a sus necesidades.

  1. El GNU Scientific Library es un software GPL escrita en C. Por lo tanto, tiene una asignación C-como y el modo de programación (punteros, etc.). Con el GSLwrap, puede tener una forma C++ de programación, mientras sigue usando el GSL. GSL tiene una implementación de BLAS, pero puede usar ATLAS en lugar del CBLAS predeterminado, si quiere incluso más actuaciones.

  2. La biblioteca boost/uBLAS es una biblioteca BSL, escrita en C++ y distribuida como un paquete de impulso. Es una forma C++ de implementar el estándar BLAS. uBLAS viene con algunas funciones de álgebra lineal, y hay un experimental binding to ATLAS.

  3. eigen es una biblioteca de álgebra lineal escrito en C++, distribuido bajo la LGPL3 (o GPL2). Es una forma de programación en C++, pero más integrada que las otras dos (hay más algoritmos y estructuras de datos disponibles). Eigen claim to be faster que las implementaciones de BLAS anteriores, sin seguir la API BLAS estándar de facto. Eigen no parece poner mucho esfuerzo en la implementación paralela.

  4. Armadillo es la biblioteca LGPL3 para C++. Tiene vinculante 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).

Estas alternativas son realmente buenas si solo quieres obtener estructuras de datos y álgebra lineal básica. Dependiendo de su gusto sobre el estilo, la licencia o los desafíos de sysadmin (la instalación de grandes bibliotecas como LAPACK puede ser difícil), puede elegir la que mejor se adapte a sus necesidades.

+0

-1 Tomar las respuestas de todos los demás en el hilo y agruparlas como su 'respuesta' es bastante cojo. Debería haber respondido con boost/uBLAS, eso es nuevo. –

+6

Lo creas o no, mi respuesta es el resultado de mi propia búsqueda, hace un mes. Creía que reunir información que me ayudó a elegir sería de algún interés. No estoy seguro de si es mejor tener varias informaciones repartidas entre las respuestas. Todavía puede votar mejor que todos si se siente más preocupado por la ética que por la eficiencia. – nojhan

+12

Lamentablemente, ninguno de estos proporciona nada tan general y conveniente como matrices numpy. Las matrices Numpy son arbitrariamente dimensionales y admiten cosas como 'a [: 4, :: - 1,:, 19] = b [Ninguna, -5:, Ninguna]' o 'a [a> 5] = 0' y similares , además de tener un gran conjunto de funciones de manipulación de matriz e índice disponibles. Realmente espero que alguien haga algo así para C++ algún día. – amaurea

-5

Todo esto es posible utilizando la biblioteca de plantillas estándar (STL) que está disponible como parte de la mayoría de las implementaciones del compilador. ¿Has mirado a STL?

+5

Sí, si está preparado para escribir todas las operaciones de matemáticas usted mismo. –

+8

Y después de haber depurado las docenas de errores que probablemente va a introducir en el proceso de escritura, descubrirá que numpy es un factor 5 más eficiente, lo que significa volver a escribir todo su código, introduciendo cientos de ellos. de errores en el proceso ... Realmente no es una buena idea. – Voo

3

Eigen es una buena biblioteca de álgebra lineal.

http://eigen.tuxfamily.org/index.php?title=Main_Page

Es muy fácil de instalar, ya que es una biblioteca sólo de encabezado. Se basa en la plantilla para generar código bien optimizado. Vectoriza automáticamente las operaciones de la matriz.

También es totalmente compatible con las operaciones de coeficiente sabio, como la "multiplicación por elemento" entre dos matrices, por ejemplo. Es lo que necesitas?

+0

Sin embargo, la sintaxis de Eigen es bastante terrible. No hay nada de esa sintaxis de corte suave que encuentras en Numpy. Y no es una biblioteca de matriz n-dimensional general, es más para vectores 1D y matrices 2D solamente. El hecho de que tengan VectorXd para matrices 1D y MatrixXd para matrices 2D me repele ya. – Alex

0

Eigen es una biblioteca de plantillas para álgebra lineal (matrices, vectores ...). Es solo encabezado y de uso gratuito (LGPL).

0

El GSL es genial, hace todo lo que está preguntando y mucho más. Sin embargo, tiene licencia bajo GPL.

1

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).El inconveniente es que Blitz ++ no tiene funciones de álgebra lineal más allá de las operaciones básicas de entrada y las contracciones del tensor. El desarrollo parece haberse desacelerado hace bastante tiempo, pero tal vez sea solo porque la biblioteca hace lo que hace y no es necesario hacer muchos cambios.

1

VIGRA contiene una buena aplicación de N dimensiones matriz:

http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html

lo uso mucho, y resulta muy sencilla y eficaz. 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 usar NumPy en términos de su API.

El inconveniente principal es que no se usa tanto como los demás, por lo que no encontrará mucha ayuda en línea. Eso, y se llama torpemente (¡intente buscarlo!)

-1

Mientras que GLM está diseñado para enredarse 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 los tipos de matriz vector &, así como varias operaciones en ellos.

Multiplicar dos matrices es un simple como (M1 * M2). Restando dos vectores (V1-V2).

El acceso a valores contenidos en vectores o matrices es igualmente simple. Después de declarar un vector vec3, por ejemplo, uno puede acceder a su primer elemento con vector.x. Echale un vistazo.

6

DyND está diseñado para ser, entre otras cosas, una biblioteca de tipo NumPy para C++. Cosas como broadcasting, arithmetic operators y slicing funcionan bien. Por otro lado, todavía es muy experimental y muchas características aún no se han implementado.

Aquí es una implementación simple del algoritmo de de Casteljau en C++ utilizando matrices 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; 
} 

me escribió una blog post un poco de tiempo de vuelta con más ejemplos y comparaciones de lado a lado de la sintaxis de Fortran 90 , DyND en C++ y NumPy en Python.

Descargo de responsabilidad: soy uno de los desarrolladores actuales de DyND.

15

Pruebe xtensor. (Ver el NumPy to Xtensor Cheat Sheet).

xtensor es una biblioteca C++ diseñada para el análisis numérico con expresiones de matriz multidimensionales.

xtensor proporciona

  • un sistema de expresión extensible que permite la difusión de estilo numpy.
  • una API siguiendo los modismos de la biblioteca estándar de C++.
  • herramientas para manipular expresiones de matriz y construir sobre xtensor.

Ejemplo

inicializar una matriz 2-D y calcular la suma de uno de sus filas y una matriz de 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} 

inicializar un array 1-D y remodelarlo inplace.

#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}} 
Cuestiones relacionadas