2017-05-30 12 views
2

Gegeben ein Vektor von Real c und ein Vektor von ganzen Zahlen rw, möchte ich einen Vektor z mit Elementen z_i=c_i^rw_i erstellen. Ich habe versucht, dies mit der komponentenweisen Funktion pow zu tun, aber ich bekomme einen Compilerfehler.Eigen: Vektor oder Matrix komponentenweise zur Potenz?

#include <Eigen/Core> 

typedef Eigen::VectorXd RealVector; 
typedef Eigen::VectorXi IntVector; // dynamically-sized vector of integers 
RealVector c; c << 2, 3, 4, 5; 
IntVector rw; rw << 6, 7, 8, 9; 
RealVector z = c.pow(rw); **compile error** 

Der Compiler-Fehler ist

error C2664: 'const Eigen::MatrixComplexPowerReturnValue<Derived> Eigen::MatrixBase<Derived>::pow(const std::complex<double> &) const': cannot convert argument 1 from 'IntVector' to 'const double &' 
     with 
     [ 
      Derived=Eigen::Matrix<double,-1,1,0,-1,1> 
     ] 
c:\auc\sedanal\LammSolve.h(117): note: Reason: cannot convert from 'IntVector' to 'const double' 
c:\auc\sedanal\LammSolve.h(117): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 

Was ist mit diesem Code falsch? Und angenommen, es kann repariert werden, wie würde ich die gleiche Operation durchführen, wenn c eine reelle Matrix anstelle eines Vektors ist, um c_ij^b_i für alle Elemente von c zu berechnen?

Compiler ist Visual Studio 2015 von Windows unter 64-Bit-Lauf 7.

Antwort

2

Zu allererst ist MatrixBase::pow eine Funktion, die die Matrix-Leistungs einer quadratischen Matrix berechnet (wenn die Matrix eine Eigenwert-Dekomposition hat, ist es die gleiche Matrix, aber mit den Eigenwerten, die zu der gegebenen Macht erhoben werden).

Was Sie wollen, ist eine elementweise Leistung, die, da es keine cwisePow Funktion in MatrixBase gibt, erfordert, auf die Array-Domäne zu wechseln. Darüber hinaus gibt es keine ganzzahlige Spezialisierung für die Potenzen (dies könnte effizient sein, aber nur bis zu einem bestimmten Schwellenwert - und die Überprüfung dieses Schwellenwerts für jedes Element würde Rechenzeit verschwenden). Daher müssen Sie die Exponenten in den Typ umwandeln deiner Matrix.

auch, um Ihre Bonus-Frage zu beantworten:

#include <iostream> 
#include <Eigen/Core> 

int main(int argc, char **argv) { 
    Eigen::MatrixXd A; A.setRandom(3,4); 
    Eigen::VectorXi b = (Eigen::VectorXd::Random(3)*16).cast<int>(); 

    Eigen::MatrixXd C = A.array() // go to array domain 
     .pow(    // element-wise power 
      b.cast<double>() // cast exponents to double 
      .replicate(1, A.cols()).array() // repeat exponents to match size of A 
     ); 

    std::cout << A << '\n' << b << '\n' << C << '\n'; 
} 

Im Wesentlichen dieser C(i,j) = std::pow(A(i,j), b(i)) für jeden i, j nennen. Wenn alle Ihre Exponenten klein sind, könnten Sie tatsächlich schneller sein als das mit einer einfachen verschachtelten Schleife, die eine spezialisierte pow(double, int) Implementierung aufruft (wie gcc's __builtin_powi), aber Sie sollten das mit tatsächlichen Daten vergleichen.

+0

Ich verließ mich auf "Katalog der Koeffizienten-weise mathematische Funktionen" (https://eigen.tuxfamily.org/dox/group__CoeffwiseMathFunctions.html), die Power-Funktionen a.pow (b) sagt; pow (a, b); \t erhöht eine Zahl auf die angegebene Potenz ($ a_i^{b_i} $) a und b kann entweder ein Array oder ein Skalar sein. \t mit Std :: Pow; pow (a [i], b [i]); (plus für Integer-Typen eingebaut) – Woody20

Verwandte Themen