2017-02-26 6 views
3

Ich möchte eine C++ - Klasse implementieren, die einen Vektor Tensoren als Mitglied hat. Die Abmessungen der Tensoren sind nicht vordefiniert, sondern nehmen Werte gemäß einiger Eingabedaten an. Außerdem können die Reihen der Tensoren unterschiedlich sein. Etwas wie folgt aus:C++ Eigen: dynamischer Tensor

std::vector<TensorXd> myTensors; 

In Eigen jedoch gibt es keine solche TensorXd Typ für dynamische Tensoren.

für jeden Tensor konstruieren, werde ich einen Vektor von Daten std::vector<double> values gelesen, die einen Tensor Dimension darstellt n x n x ... x n (r mal). Etwas wie dieses:

Tensor<double, r> tensor = TensorMap<double, r>(values.data(), std::vector<size_t>(r, n); 
myTensors.push_back(tensor); 

Ist es möglich, das zu tun?

Vielen Dank im Voraus für Ihre Hilfe!

Update:

Als Jaroslaw Bulatov wies darauf hin, Eigen bietet keine Unterstützung für dynamischen Rang und somit haben die unterstützten Reihen explizit ausgeschrieben werden. In meinem Code:

#include <iostream> 
#include <vector> 
#include <Eigen/Dense> 
#include <unsupported/Eigen/CXX11/Tensor> 

typedef Eigen::Tensor< double , 3 > Tensor3d; 
typedef Eigen::Tensor< double , 4 > Tensor4d; 
typedef Eigen::Tensor< double , 5 > Tensor5d; 
typedef Eigen::Tensor< double , 6 > Tensor6d; 
typedef Eigen::Tensor< double , 7 > Tensor7d; 
typedef Eigen::Tensor< double , 8 > Tensor8d; 
typedef Eigen::Tensor< double , 9 > Tensor9d; 
typedef Eigen::Tensor< double , 10 > Tensor10d; 

class MyClass 
{ 
private:       
    Eigen::MatrixXd Potentials_1;    
    std::vector<Eigen::MatrixXd> Potentials_2; 
    std::vector<Tensor3d> Potentials_3; 
    std::vector<Tensor4d> Potentials_4; 
    std::vector<Tensor5d> Potentials_5; 
    std::vector<Tensor6d> Potentials_6; 
    std::vector<Tensor7d> Potentials_7; 
    std::vector<Tensor8d> Potentials_8; 
    std::vector<Tensor9d> Potentials_9; 
    std::vector<Tensor10d> Potentials_10; 

public: 
    MyClass(); 
    void setPotentials_1(const Eigen::MatrixXd &_Potentials_1){ Potentials_1 = _Potentials_1; } 
    void setPotentials_2(const std::vector<Eigen::MatrixXd> &_Potentials_2){ Potentials_2 = _Potentials_2; } 
    void setPotentials_3(const std::vector<Tensor3d> &_Potentials_3){ Potentials_3 = _Potentials_3; } 
    void setPotentials_4(const std::vector<Tensor4d> &_Potentials_4){ Potentials_4 = _Potentials_4; } 
    void setPotentials_5(const std::vector<Tensor5d> &_Potentials_5){ Potentials_5 = _Potentials_5; } 
    void setPotentials_6(const std::vector<Tensor6d> &_Potentials_6){ Potentials_6 = _Potentials_6; } 
    void setPotentials_7(const std::vector<Tensor7d> &_Potentials_7){ Potentials_7 = _Potentials_7; } 
    void setPotentials_8(const std::vector<Tensor8d> &_Potentials_8){ Potentials_8 = _Potentials_8; } 
    void setPotentials_9(const std::vector<Tensor9d> &_Potentials_9){ Potentials_9 = _Potentials_9; } 
    void setPotentials_10(const std::vector<Tensor10d> &_Potentials_10){ Potentials_10 = _Potentials_10; } 
}; 

Yaroslav auch vorgeschlagen, dass mit Hilfe von Makros helfen kann, um Code-Duplizierung ungültig. Ich bin nicht vertraut mit C++ - Makros, daher würde jede Hilfe sehr geschätzt werden.

Danke für Ihre Hilfe!

+0

Eigen unterstützt keine dynamischen Ränge, daher muss jeder unterstützte Rang explizit ausgeschrieben werden, indem Makros verwendet werden, um Codeverdopplung zu sparen. Siehe https://github.com/tensorflow/tensorflow/commit/eaf96c45 für ein Beispiel zum Hinzufügen von Unterstützung für ein paar zusätzliche Ränge zu ops –

+0

@ YaroslavBulatov Danke. Ich bin nicht vertraut mit C++ - Makros. Könntest du bitte das Update lesen und mir sagen, wie ich Makros in meinem Fall benutze? Vielen Dank! – Khue

Antwort

1

Sie können die Xtensor C++ - Vorlagenbibliothek auschecken, die sowohl dynamische als auch statische Dimensionalität unterstützt.

http://xtensor.readthedocs.io/en/latest/

Xtensor hat eine API, die zu dem von numpy sehr ähnlich ist, einschließlich der Vektorisierung, die Sendung, universelle Funktion. Es gibt ein numpy Spickzettel Xtensor hier: http://xtensor.readthedocs.io/en/latest/numpy.html

Schließlich können Sie versuchen, es durch einen Klick auf dem Bindemittel Abzeichen an der Spitze des https://github.com/QuantStack/xtensor/

Xtensor in einem C++ Jupyter Notebook leben kommt auch mit Anbindung für das Haupt Sprachen des wissenschaftlichen Rechnens (R, Julia, Python).

+0

Danke. Schön! Aber wie vergleicht sich xtensor mit dem eigenen Tensor in Bezug auf die Leistung? Besonders bei der Tensorkontraktion (was eine Schlüsseloperation in meinem Projekt ist). – Khue

+0

Es gibt keine systematische Benchmark. Die SIMD-Beschleunigung wurde erst kürzlich in xtensor gesteckt. – Quant

+0

Ich habe die Dokumente überprüft und es scheint, dass xtensor Tensor Kontraktion noch nicht unterstützt. Genauer gesagt muss ich das (innere) Produkt eines D-dimensionalen Tensors mit (D-1) Vektoren ausführen (und somit ist das Ergebnis ein Vektor). Ist es möglich, dies effizient in xtensor zu tun? Ich denke, ich sollte eine separate Frage stellen. – Khue