2012-06-23 11 views
41

Esistono librerie C++ (o C) con matrici simili a NumPy con supporto per operazioni di slicing, vettorializzazione, aggiunta e sottrazione di contenuti elemento-per-elemento, ecc.?Array di stile NumPy per C++?

+2

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

+0

Per quanto ne so utilizza numpy [LAPACK] (http://en.wikipedia.org/wiki/LAPACK). Mentre questo è scritto in Fortran, ci sono i collegamenti C++ disponibili. Mai usato nessuno di quelli però. – Voo

+0

C'è un'interfaccia C++ recente a NumPy, chiamata [ArmaNpy] (https://sourceforge.net/projects/armanpy/). – mtall

risposta

28

Ecco alcuni software gratuiti che possono soddisfare le vostre esigenze.

  1. Il GNU Scientific Library è un software GPL scritta in C. Quindi, ha un'allocazione C-like e modo di programmazione (puntatori, etc.). Con lo GSLwrap, è possibile avere un modo di programmazione C++, mentre si utilizza ancora il GSL. GSL ha un'implementazione BLAS, ma puoi usare ATLAS invece del CBLAS predefinito, se vuoi ancora più prestazioni.

  2. La libreria boost/uBLAS è una libreria BSL, scritta in C++ e distribuita come pacchetto boost. È un modo C++ per implementare lo standard BLAS. uBLAS ha alcune funzioni di algebra lineare e c'è un experimental binding to ATLAS.

  3. eigen è una libreria di algebra lineare scritta in C++, distribuita sotto LGPL3 (o GPL2). È un modo di programmazione C++, ma più integrato rispetto agli altri due (sono disponibili più algoritmi e strutture dati). Eigen claim to be faster rispetto alle implementazioni BLAS di cui sopra, pur non rispettando l'API BLAS standard di fatto. Eigen non sembra impegnarsi molto nell'implementazione parallela.

  4. Armadillo è la libreria LGPL3 per C++. È vincolante per LAPACK (la libreria utilizzata da numpy). Usa i modelli ricorsivi e la meta-programmazione dei template, che è un buon punto (non so se anche altre librerie lo fanno).

Queste alternative sono davvero buone se si desidera ottenere solo strutture dati e algebra lineare di base. A seconda del tuo gusto riguardo alle sfide di stile, licenza o sysadmin (l'installazione di grandi librerie come LAPACK può essere difficile), puoi scegliere quella più adatta alle tue esigenze.

+0

-1 Prendendo le risposte di tutti gli altri nella discussione e raggruppandole insieme come 'risposta' è piuttosto zoppa. Dovrebbe aver appena risposto con boost/uBLAS, questo è nuovo. –

+6

Che ci crediate o no, la mia risposta è il risultato della mia ricerca, qualche mese fa. Credevo che raccogliere le informazioni che mi hanno aiutato a fare la mia scelta sarebbe stato di qualche interesse. Non sono sicuro che sia meglio avere diverse informazioni diffuse tra le risposte. Puoi ancora invidiare tutti se ti senti più interessato all'etica che all'efficienza. – nojhan

+12

Purtroppo, nessuno di questi fornisce nulla di generico e conveniente come gli array numpy. Gli array Numpy sono a dimensione arbitraria e supportano cose come 'a [: 4, :: - 1,:, 19] = b [Nessuno, -5:, Nessuno]' o 'a [a> 5] = 0' e simili , oltre ad avere un enorme set di funzioni di manipolazione di indici e di manipolazione disponibili. Spero davvero che qualcuno faccia qualcosa del genere per C++ un giorno. – amaurea

-5

Tutte queste cose sono possibili utilizzando la libreria di modelli standard (STL) che è disponibile come parte della maggior parte delle implementazioni del compilatore. Hai guardato STL?

+5

Sì, se sei pronto a scrivere da solo tutte le operazioni matematiche. –

+8

E dopo aver eseguito il debug delle dozzine di bug che probabilmente introdurrai nel processo di scrittura, scoprirai che numpy è un fattore 5 più efficiente, che quindi significa riscrivere tutto il tuo codice, introducendo quindi sicuramente centinaia di bug nel processo .. No davvero non è una buona idea. – Voo

3

Eigen è una buona libreria di algebra lineare.

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

è abbastanza facile da installare in quanto si tratta di una libreria di testa-solo. Si basa sul modello per generare codice ottimizzato. Vectorizza automaticamente le operazioni della matrice.

Supporta inoltre pienamente le operazioni di coefficiente saggio, come ad esempio la "moltiplicazione per elemento" tra due matrici. È quello che ti serve?

+0

La sintassi di Eigen è piuttosto terribile. Non c'è nessuno di quella sintassi liscia che si trova in Numpy. E non è una libreria di array n-dimensionale generale, è solo per i vettori 1D e solo per le matrici 2D. Il fatto che abbiano VectorXd per gli array 1D e MatrixXd per gli array 2D mi respinge già. – Alex

0

Eigen è una libreria di modelli per algebra lineare (matrici, vettori ...). È solo intestazione e libero di usare (LGPL).

0

Il GSL è fantastico, fa tutto quello che stai chiedendo e molto altro. Tuttavia è concesso sotto licenza GPL.

1

Blitz++ supporta matrici con un numero arbitrario di assi, mentre Armadillo supporta solo fino a tre (vettori, matrici e cubi). Eigen supporta solo vettori e matrici (non cubi).Il rovescio della medaglia è che Blitz ++ non ha funzioni di algebra lineare oltre alle operazioni base entrywise e contrazioni tensoriali. Lo sviluppo sembra essere rallentato un po 'di tempo fa, ma forse è solo perché la libreria fa quello che fa e non è necessario apportare molte modifiche.

1

VIGRA contiene una buona implementazione con array N-dimensionale:

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

lo uso ampiamente, e trovato molto semplice ed efficace. È anche solo intestazione, quindi è molto facile da integrare nel tuo ambiente di sviluppo. È la cosa più vicina che mi sia capitato di usare NumPy in termini di API.

Lo svantaggio principale è che non è così ampiamente utilizzato come gli altri, quindi non troverete molto aiuto online. Questo, ed è chiamato in modo imbarazzante (prova a cercarlo!)

-1

Mentre il GLM è progettato per collegarsi facilmente con OpenGL e GLSL, è un'intestazione completamente funzionale solo per la libreria di matematica per C++ con un insieme di interfacce molto intuitivo.

Dichiara il vettore & tipi di matrice e varie operazioni su di essi.

La moltiplicazione di due matrici è semplice come (M1 * M2). Sottraendo due vettori (V1- V2).

L'accesso ai valori contenuti in vettori o matrici è altrettanto semplice. Ad esempio, dopo aver dichiarato un vettore vec3, è possibile accedere al suo primo elemento con vector.x. Controlla.

6

DyND è progettato per essere, tra le altre cose, una libreria simile a NumPy per C++. Cose come broadcasting, operatori aritmetici e slicing funzionano bene. D'altra parte, è ancora molto sperimentale e molte funzionalità non sono ancora state implementate.

Ecco una semplice implementazione dell'algoritmo de Casteljau in C++ usando array 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; 
} 

ho scritto un blog post un po 'indietro con più esempi e confronti side-by-side della sintassi per Fortran 90 , DyND in C++ e NumPy in Python.

Disclaimer: Sono uno degli attuali sviluppatori di DyND.

15

Prova xtensor. (Vedi lo NumPy to Xtensor Cheat Sheet).

xtensor è una libreria C++ destinata all'analisi numerica con espressioni di array multidimensionale.

xtensor fornisce

  • un sistema di espressione estensibile che consente la trasmissione NumPy stile.
  • un'API che segue gli idiomi della libreria standard C++.
  • strumenti per manipolare le espressioni di matrice e costruire su xtensor.

Esempio

Inizializzare una matrice 2-D e calcolare la somma di una delle sue righe e una matrice 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; 

uscite

{7, 11, 14} 

inizializzare un array di 1-D e rimodellare 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; 

uscite

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