uBLAS: reference to container data & iteratordeclaration
From my questions about argument types I know that m.column(2) is a kind of an expression. How can I get the underlying reference to data if
Hi, *) First question: I am trying to get a reference to data of a container in the following way: matrix<double> m(3,3); vector<double>& v(m.column(2)); But this seems not to be possible. Is there a way to achieve this behaviour? What I basically want to achive is having functor object that holds a reference to a row/column of my container matrix. there even is one? *) Second question: matrix<double> m(10,3); ... fill the matrix ... matrix<double>::iterator it; // wrong this does not work!! for (it = m.column(2).begin(); it != m.colum(2).end(); ++it) { cout << *it << " " << foo(*it) << endl; } How would I declare my iterator? I understand when I use std::library-algorithms the automatic template parameter defer will give me the correct type from begin(). But in my case how should I declare the iterator? Thank you for help. Roland
Hi,
*) First question:
I am trying to get a reference to data of a container in the following way:
matrix<double> m(3,3); vector<double>& v(m.column(2));
But this seems not to be possible.
Is there a way to achieve this behaviour?
Either use
matrix_column
What I basically want to achive is having functor object that holds a reference to a row/column of my container matrix.
Looks like you'll need [1].
From my questions about argument types I know that m.column(2) is a kind of an expression. How can I get the underlying reference to data if there even is one?
You could start with m.column(2).data() and traverse the expression tree then. In my experience this only is needed for special applications like bindings to external libraries. I'd generally advise against using it.
*) Second question:
matrix<double> m(10,3);
... fill the matrix ...
matrix<double>::iterator it; // wrong this does not work!!
for (it = m.column(2).begin(); it != m.colum(2).end(); ++it) { cout << *it << " " << foo(*it) << endl; }
How would I declare my iterator? I understand when I use std::library-algorithms the automatic template parameter defer will give me the correct type from begin(). But in my case how should I declare
matrix_column
iterator?
HTH, Joerg
Either use
matrix_column
v (m.column (2)); // proxy[1] or
vector<double> v (m.column (2)); // copy
Thank you so much. That seems to be exactly what I was looking for.
BTW.: It seems that "matrix_column
*) Second question: ...
matrix_column
::iterator it;
This is clear to me now. I've RTFM'd ;-) and found the example using the free column() functions. Roland
Hi,
Either use
matrix_column
v (m.column (2)); // proxy[1] or
vector<double> v (m.column (2)); // copy
Thank you so much. That seems to be exactly what I was looking for.
BTW.: It seems that "matrix_column
c "can be used as a reference to any other 'vector-like' type, as the following also works: c = v; // v beeing a vector; c = m.row(2); c = m.col(0);
Nope. You're overwriting the referenced part of the matrix three times now.
There is still an interesting point: While it is possible to assign a row to the matrix_column it is not possible to supply a row in the constructor call. What is the rationale behind this?
The constructor constructs the proxy, the assignment operator assigns to the proxied elements.
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express this more concise.)
I hope, we'll be able to solve this, too. Best, Joerg
The constructor constructs the proxy, the assignment operator assigns to the proxied elements.
Oh yes, I can see now, thank you.
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express
this
more concise.)
I hope, we'll be able to solve this, too.
I am not sure about your last statement. Do you mean a kind of 'vector_proxy' that can act as a placeholder to a row/column or another vector? Roland
Hi, [snip]
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express this more concise.)
I hope, we'll be able to solve this, too.
I am not sure about your last statement. Do you mean a kind of 'vector_proxy' that can act as a placeholder to a row/column or another vector?
No, I basically meant, I hope that you'll find appropriate signatures for your functions. I still believe you'll either have to use 'expressions' or have to enumerate all overloads for your 'data' types (and that could be many ;-). Sorry for the confusion, Joerg
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express this more concise.)
I hope, we'll be able to solve this, too.
I am not sure about your last statement. Do you mean a kind of 'vector_proxy' that can act as a placeholder to a row/column or another vector?
No, I basically meant, I hope that you'll find appropriate signatures for your functions. I still believe you'll either have to use 'expressions' or have to enumerate all overloads for your 'data' types (and that could be many ;-).
So in a certain sense I can see the 'expression' that is stored in my functor as a 'reference' to my container data? I.e when the data of the container changes the evaluation of the expression will retrieve the current data? Sorry for my slow uptake on the matter. I think this comes from the fact that I still do not have a sound idea of what an 'expression' is to me from a point of usage. Can I see it as a bundle of funtions having certain parameter lists? What 'really' happens when I "e() (i,j)" ? Regards, Roland
Hi, [snip]
I am not sure about your last statement. Do you mean a kind of 'vector_proxy' that can act as a placeholder to a row/column or another vector?
No, I basically meant, I hope that you'll find appropriate signatures for your functions. I still believe you'll either have to use 'expressions' or have to enumerate all overloads for your 'data' types (and that could be many ;-).
So in a certain sense I can see the 'expression' that is stored in my functor as a 'reference' to my container data? I.e when the data of the container changes the evaluation of the expression will retrieve the current data?
Hm, more or less yes
Sorry for my slow uptake on the matter. I think this comes from the fact that I still do not have a sound idea of what an 'expression' is to me from a point of usage. Can I see it as a bundle of funtions having certain parameter lists?
I'd tend to see it as the root of an expression tree build from class objects (at compile time).
What 'really' happens when I "e()(i,j)" ?
The expression is interpreted (at compile time ;-) Best, Joerg
Hi Joerg,
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express this more concise.)
I hope, we'll be able to solve this, too.
Finally I found a solution that works with expressions, without the
burden of template parameter specification. I took up your suggestion
and blended it with boost::function. I would be glad if you could
have a look on it and perhaps comment.
=====================================================================
#include <iostream>
#include
Hi Roland, you wrote:
If the constructor also would accept a row I could use it as a parameter type for function calls when I want to express, that only 'data' types are expected and 'expressions' are not wanted. (Sorry for the sloppy formulation, I am not sure how to express this more concise.)
I hope, we'll be able to solve this, too.
Finally I found a solution that works with expressions, without the burden of template parameter specification. I took up your suggestion and blended it with boost::function. I would be glad if you could have a look on it and perhaps comment. ==================================================================== #include <iostream> #include
#include #include #include #include using namespace boost::numeric::ublas; // this is the class that implements the functor // it also could be parameterized on more than one expression // (this is what Joerg suggested) template
class func_impl { public: func_impl(const vector_expression<E> &e) : e_ (e) {}
func_impl(const vector_expression<E> &e) : e_ (e ()) {}
T operator() (const T& x){ // algorithm goes here ... return e_()(0)*x; // just for demonstration } private: const vector_expression<E> &e_;
// Storing the closure type should prevent some subtle lifetime issues // when chaining functions for example... typename E::const_closure_type e_;
};
// this is the user part of the functor // the constructor is used to act as a generator for the // implementation type. template<class T> class func : public boost::function1
{ public: template<class E> func(const vector_expression<E>& e) : boost::function1 (func_impl (e)) {} }; int main(int argc, char* argv[]) { matrix<double> m (3,3); vector<double> v (3); func<double> f(m.row(0)); // notice: no need to know the type of m.row
m(0,0) = 0.0; m(0,1) = 0.1; m(0,2) = 0.2; m(1,0) = 1.0; m(1,1) = 1.1; m(1,2) = 1.2; m(2,0) = 2.0; m(2,1) = 2.1; m(2,2) = 2.2;
std::cout << f(1.0) << std::endl; // outputs: 0
m(0,0) = 47.11; // change the referenced matrix std::cout << f(1.0) << std::endl; // outputs: 47.11
// other argument types ... func<double> f1(m.column(2)); std::cout << f1(1.0) << std::endl; // outputs: 0.2 m(0,2) = 13; std::cout << f1(1.0) << std::endl; // outputs: 13
// similar with vector ... func<double> f2(v);
return 0; } ====================================================================
Of course this involves an indirection since I am using the functiom.hpp from boost as base class. But I think this is not avoidable in principle, since this is what a reference is all about, isn't it?
Impressed-by-this-nice-combination-of-different-libraries-ly y'rs Joerg
participants (3)
-
jhr.walter@t-online.de
-
speedsnaii
-
speedsnaii <speedsnaii@yahoo.de>