Me gustaría utilizar la biblioteca de matriz Eigen como motor de álgebra lineal en mi programa. Eigen usa plantillas de expresión para implementar evaluación diferida y simplificar bucles y cálculos.¿Cómo integrar una biblioteca que usa plantillas de expresión?
Por ejemplo:
#include<Eigen/Core>
int main()
{
int size = 40;
// VectorXf is a vector of floats, with dynamic size.
Eigen::VectorXf u(size), v(size), w(size), z(size);
u = 2*v + w + 0.2*z;
}
Desde Eigen utiliza plantillas de expresión, código como
u = 2*v + w + 0.2*z;
En la muestra se ha mencionado anteriormente se reduce a un solo bucle de longitud 10 (no 40, los flotadores se ponen en register por trozos de 4) sin crear un temporal. ¿Cuan genial es eso?
Pero si integro la biblioteca de la siguiente manera:
class UsingEigen
{
public:
UsingEigen(const Eigen::VectorXf& data):
data_(data)
{}
UsingEigen operator + (const UsingEigen& adee)const
{
return UsingEigen(data_ + adee.data_);
}
...
private:
Eigen::VectorXf data_;
}
A continuación, las expresiones como:
UsingEigen a, b, c, d;
a = b + c + d;
no puede tomar ventaja de la forma en que se implementa Eigen. Y esto no es lo último. Hay muchos otros ejemplos, donde las plantillas de expresión se usan en Eigen.
La solución fácil sería no definir los operadores por mí mismo, hacer data_
pública y acaba de escribir expresiones como:
UsingEigen a, b, c, d;
a.data_ = b.data_ + c.data_ + d.data_;
Esto rompe la encapsulación, pero preserva la eficiencia de Eigen.
Otra forma podría ser crear mis propios operadores, pero dejarles devolver plantillas de expresión. Pero dado que soy un principiante en C++, no sé si este es el camino correcto a seguir.
Lo siento si la pregunta es de naturaleza demasiado general. Soy un principiante y no tengo a nadie que preguntar. Hasta ahora estaba usando std::vector<float>
en todas partes, pero ahora también necesito usar matrices. Pasar de std::vector<float>
a Eigen en todo mi proyecto es un gran paso y tengo miedo de hacer una llamada incorrecta desde el principio. Cualquier consejo es bienvenido!
Problema interesante. Lo primero, sin embargo, es: ¿por qué quieres encapsular los vectores de bibliotecas Eigen de esta manera? ¿Qué comportamiento agregan tus clases? –
Mis clases no agregan ninguna funcionalidad a las clases de la biblioteca Eigen, pero úselas. Por ejemplo, una de mis clases principales almacena dos vectores. Uno como entrada para un cierto cálculo matemático y el otro como salida. Estos objetos necesitan interoperar de una manera similar a la mencionada anteriormente. Cuando agrega dos objetos de este tipo, las entradas deben agregarse. –
No creo que esto sea posible sin la reproducción de una parte sustancial del framework de plantilla de expresión usted mismo. Por ejemplo, '(a + b) * c' será algo así como' ExprCwiseAdd * UsingEigen' (el nombre está compuesto, no lo recuerdo más), y tendrá que haber 'ExprCwiseAdd * UsingEigen' definido en alguna parte , pero también 'ExprCwiseAdd * ExprCWiseAdd' y así sucesivamente. En resumen, la adición no tendrá 'UsingEigen' como tipo de devolución. (Puede echarle un vistazo a [boost :: proto] (http://www.boost.org/doc/libs/1_49_0/doc/html/proto.html) que es un marco para plantillas de expresiones). Buena suerte. – eudoxos