UBLAS: advice on argument types please

I am trying to find a good choice for argument types to a function. (Please be patient, I am a poor user of C++ who has not yet understood all this expression template magic.) I'd like to have a function: void foo( whattype arg) { } matrix<double> m(3,3); vector<double> v(6); and call it like: foo(m.column(0)); foo(m.row(0)); foo(v); Is this feasible? Should I use iterators for whattype? (how do I access size information then?) Am I trying to misuse the ublas when asking such a question? (Which container should I use in this case?) In the hope anyone can shade some light on it. Thank you, Roland

Hi Roland, you wrote:
I am trying to find a good choice for argument types to a function.
(Please be patient, I am a poor user of C++ who has not yet understood all this expression template magic.)
I'd like to have a function:
void foo( whattype arg) { }
matrix<double> m(3,3); vector<double> v(6);
and call it like:
foo(m.column(0)); foo(m.row(0)); foo(v);
Is this feasible?
I'd tend to use template<class E> void foo (vector_expression<E> &arg); or template<class E> void foo (const vector_expression<E> &arg);
Should I use iterators for whattype?
Unsure about that.
(how do I access size information then?)
it ().size ();
Am I trying to misuse the ublas when asking such a question?
Nope.
(Which container should I use in this case?)
No need to copy yet.
In the hope anyone can shade some light on it.
HTH, Joerg

Hi Joerg, thank you. I think I am starting to learn (steep slope ;-).
I'd tend to use
template<class E> void foo (vector_expression<E> &arg);
or
template<class E> void foo (const vector_expression<E> &arg);
Can I see this as specifying the base classes of my argument types?
Should I use iterators for whattype?
Unsure about that.
I tried to do it, but there seem to be some problems with VC60 (distance_type instead of difference_type, iterator_traits don't work because of unsopported partial specialization, ...)
(Which container should I use in this case?)
No need to copy yet.
Ok, these arguments are expressions. But now I ran into the following: ============================================================= template<class E> struct func { func(const matrix_expression<E>& arg) : e(arg) {} typename E::value_type operator() () { return e[e.size1()-1]; }; private: //const matrix_expression<E>& e; // error-> size1 not a member of matrix_expression const matrix_reference<E> e; // doesn't work either... }; int main(int argc, char* argv[]) { matrix<double> v (3,3); func<matrix<double> > f(v); f(); return 0; } ============================================================= I think I do not yet understand of how to use the matrix_reference, do I? Using matrix_const_reference instead gives me an error that I have no glue what is going on: error C2143: syntax error : missing ';' before '<' regards, roland

I think I found out now, what I was missing. I am working with expressions now, and so I have to refer to the arguments as arg().size() But this still leaves me with even more questions: Why would I prefer: template<class E> void foo(const vector_expression<E>& arg) { arg().size(); } over template<class V> void foo(const V& arg) { arg.size(); } ? When rethinking my problem it seems to me as if I would need to decide whether my algorithm should work on expressions or on containers. But where is my container? vector is a container and an expression. This confuses me somewhat. Ok, my original question was of how to foo(m.column(0)) or foo(m.row(1)) and this automatically made an expression from my rows/cols. So creating my subroutine in a way is implementing an algorithm. But as I feel this is different from what uBLAS does in functional.hpp, isn't it? What I originally was looking for was a container concept similar to std::vector that extends to matrix. I am aware that uBLAS is much more powerful, but leaves me with the question of how to write my own subroutines. Could you Joerg or anyone else give me some ideas of how to do this (conceptually simple) task or point me to some example code? Thank you for your help, Roland

Hi Roland, you wrote:
I think I found out now, what I was missing. I am working with expressions now, and so I have to refer to the arguments as
arg().size()
Correct.
But this still leaves me with even more questions:
Why would I prefer:
template<class E> void foo(const vector_expression<E>& arg) { arg().size(); }
over
template<class V> void foo(const V& arg) { arg.size(); }
?
You could overload foo() for vector_expression<> and matrix_expression<> then. Sorry for giving the second hint first ;-)
When rethinking my problem it seems to me as if I would need to decide whether my algorithm should work on expressions or on containers.
Hm. In a certain way, yes.
But where is my container? vector is a container and an expression. This confuses me somewhat. Ok, my original question was of how to foo(m.column(0)) or foo(m.row(1)) and this automatically made an expression from my rows/cols.
Yes.
So creating my subroutine in a way is implementing an algorithm. But as I feel this is different from what uBLAS does in functional.hpp, isn't it?
Yes, functional.hpp is pretty much an implementation detail.
What I originally was looking for was a container concept similar to std::vector that extends to matrix.
Hm. Vector and matrix are different concepts IMO.
I am aware that uBLAS is much more powerful, but leaves me with the question of how to write my own subroutines.
You've lost me. Above you've pointed out both ways to declare generic functions foo(). Are you talking about the implementation of foo() now?
Could you Joerg or anyone else give me some ideas of how to do this (conceptually simple) task or point me to some example code?
I believe, I've answered this one already: http://groups.yahoo.com/group/Boost-Users/message/3028 (see the bottom of the posting). Anything wrong with that? Best regards, Joerg

Hi Joerg, first let me thank you for beeing so helpful. |> But this still leaves me with even more questions: |> |> Why would I prefer: |> |> template<class E> |> void foo(const vector_expression<E>& arg) |> { |> arg().size(); |> } |> |> over |> |> template<class V> |> void foo(const V& arg) |> { |> arg.size(); |> } |> |> ? | You could overload foo() for vector_expression<> and matrix_expression<> | then. Sorry for giving the second hint first ;-) Do you mean for the sake of getting better error diagnostics when I supply a completely unrelated type to foo? As i.e. foo(3.15)? Or did I misunderstand you? |> ... <snip> ... | You've lost me. Above you've pointed out both ways to declare generic | functions foo(). Ok, I think I understand this now. | Are you talking about the implementation of foo() now? Yes it seems so. Using either declaration will result in a separate overloaded function. (Is this referred to as code bloating?) But all I need is access to operator[] (and similar), operator(n,m), size1/2 () and the value_type basically. This is why I tried first to formulate my algorithm in terms of iterators. Somehow I am trying to discard the expression type info I think, since I am only interested in the common member functions, that let me see it as a container. Could I write a kind of vector and matrix proxy that is able to acomplish this? Would you recommend or not to take this route? BTW.: I am not sure exactly what comprises the user interface to the uBLAS. Is this what is in the documentation? Then what is vector_reference for? Why is vector_constant_reference not available and what is its purpose? Could this class be of help in my case? |> Could you Joerg or anyone else give me some ideas of how |> to do this (conceptually simple) task or point me to some example |> code? | I believe, I've answered this one already: | http://groups.yahoo.com/group/Boost-Users/message/3028 | | (see the bottom of the posting). Anything wrong with that? Oh, sorry I somehow overlooked this message. Thank you. Regards, Roland

This is an addendum to my previous post... I looked into the bayesclasses as you were suggesting and as far as I see the use of the uBLAS does something I was presuming before. There is a local Vec and Matrix class which are defined as following: ============================================================== class Vec: public ublas::vector<double> { ... template <class E> Vec(const ublas::vector_expression<E>& e) : ublas::vector<double> (e) {} // vector_expression conversion constructor ... template <class E> Vec& operator=(const ublas::vector_expression<E>& r) { // Expression assignment, may be dependant on r ublas::vector<double>::operator=(r); return *this; } ... } ============================================================== This essentially removes the expression information in the assignment. Am I right? Now when defining void foo(Vec& arg) {} there is no passing of the expression tree to the function, since it is converted to vector<double> when passed as an argument. I presume this will create a temporary, won't it? So I end up wondering whether it is a good idea to use boost::multi_arry as a container and boost:numeric::matrix for expression evaluation? Will it be easy to interface back and forth? Or is this a completely odd idea? Listening eagerly, Roland

Hi Roland, you wrote:
This is an addendum to my previous post...
I looked into the bayesclasses as you were suggesting and as far as I see the use of the uBLAS does something I was presuming before. There is a local Vec and Matrix class which are defined as following:
============================================================= class Vec: public ublas::vector<double> { ... template <class E> Vec(const ublas::vector_expression<E>& e) : ublas::vector<double> (e) {} // vector_expression conversion constructor ... template <class E> Vec& operator=(const ublas::vector_expression<E>& r) { // Expression assignment, may be dependant on r ublas::vector<double>::operator=(r); return *this; } ... } =============================================================
This essentially removes the expression information in the assignment. Am I right?
Hm. ublas' operator=() or assign() always are the point of evaluation, i.e. they never copy expression trees.
Now when defining void foo(Vec& arg) {} there is no passing of the expression tree to the function, since it is converted to vector<double> when passed as an argument. I presume this will create a temporary, won't it?
Yep. This is Michael's design decision.
So I end up wondering whether it is a good idea to use boost::multi_arry as a container and boost:numeric::matrix for expression evaluation?
You want to use boost::multi_array to get COW?
Will it be easy to interface back and forth? Or is this a completely odd idea?
During the past nobody proposed to change the default storage containers of ublas to support COW. On the contrary there were some voices emphasizing that using COW it is sometimes (too) unclear, whether a = b is a shallow copy or a deep copy. If you want to change this behaviour, you'll probably have to discuss the topic on lists.boost.org or on groups.yahoo.com/group/ublas-dev. Regards, Joerg

Hi Roland, you wrote:
|> But this still leaves me with even more questions: |> |> Why would I prefer: |> |> template<class E> |> void foo(const vector_expression<E>& arg) |> { |> arg().size(); |> } |> |> over |> |> template<class V> |> void foo(const V& arg) |> { |> arg.size(); |> } |> |> ?
| You could overload foo() for vector_expression<> and matrix_expression<> | then. Sorry for giving the second hint first ;-)
Do you mean for the sake of getting better error diagnostics when I supply a completely unrelated type to foo? As i.e. foo(3.15)? Or did I misunderstand you?
Yes. I meant that you can reuse the name foo() in vector and matrix contexts then, i.e. template<class E> void foo(const vector_expression<E>& arg); template<class E> void foo(const matrix_expression<E>& arg); [snip]
| Are you talking about the implementation of foo() now?
Yes it seems so. Using either declaration will result in a separate overloaded function. (Is this referred to as code bloating?) But all I need is access to operator[] (and similar), operator(n,m), size1/2 () and the value_type basically.
OK, I think I understand now what you're aiming at: you want ublas to give you the characteristics of (ordinary ;-) runtime polymorphism. But would you be willing to pay the performance penalty for using an virtual operator() then, for example?
This is why I tried first to formulate my algorithm in terms of iterators. Somehow I am trying to discard the expression type info I think, since I am only interested in the common member functions, that let me see it as a container. Could I write a kind of vector and matrix proxy that is able to acomplish this? Would you recommend or not to take this route?
There certainly are many cases, where runtime polymorphism is a good solution. But this doesn't hold for ublas' operator() AFAIK.
BTW.: I am not sure exactly what comprises the user interface to the uBLAS. Is this what is in the documentation?
Generally yes.
Then what is vector_reference for?
vector_reference<> is mainly needed to describe the signatures of operators returning expression templates.
Why is vector_constant_reference not available and what is its purpose?
We had a lot of discussions regarding the question, if vector_reference<const E> ~= vector_const_reference<E>. This approximation is good enough for all compilers except Borland. For more details please see the message archive of groups.yahoo.com/group/ublas-dev
Could this class be of help in my case?
Yes, if you intend to extend the expression template machinery. [snip] Regards, Joerg

Hi Joerg,
OK, I think I understand now what you're aiming at: you want ublas to give you the characteristics of (ordinary ;-) runtime polymorphism. But would you be willing to pay the performance penalty for using an virtual operator() then, for example?
I think generally not. Hmmm, but is there a way to do without? After a lot of reading and thinking and with your help :-) I came out with the following. May I show you a code snippet from my spline function to show you my actual problem? ================================================================ template<class T> class vector_proxy_base { public: virtual T operator[] (unsigned int idx) = 0; }; template<class E> class vector_proxy : public vector_proxy_base<E::value_type> { public: vector_proxy(vector_expression<E> e) : m_e(e) {} typename E::value_type operator[] (unsigned int idx) { return m_e().operator[](idx); } private: vector_expression<E> m_e; }; template<class T> class spline : public std::unary_function<T, T> { public: template<class E> spline(vector_expression<E> e) : ex(new vector_proxy<E>(e)) {} ~ppi0() { delete ex; } T operator() (const T& x){ // the spline interpolation algorithm goes here ... return ex->[0]; // do something useful ;-) // ugly, indirection and virtual function call } private: vector_proxy_base<T>* ex; }; ================================================================ I can not see a way to do this differently, since otherwise I would need to template<class T, class E> class spline { .... } where E is the expression type. But instantiating the functor then would be infeasible since I do not know the complete expression hierarchy, or at least it is too cumbersome to specify. The automatic template parameter deduction does not work for class templates as it does for funtion templates, does it? What yet is missing of course are all the other member functions that make a vector or matrix. Perhaps there is a simpler solution I do not see?
vector_reference<> is mainly needed to describe the signatures of
operators
returning expression templates.
I was trying to template<class E> void foo(vector_reference<E> e) { e.size(); // some use of e } and call it foo(m.column(0)); But my compiler chokes. So am I right, that vector_reference is not intended for this kind of usage?
groups.yahoo.com/group/ublas-dev
Oh, I may read this as an ordinary user? Didn't try this yet. Thank you for the hint. BTW.: I've delayed the idea of COW (Copy On Write?) This was before I realized that vector_expression is kind of a reference to my data. Regards, Roland

Hi Roland, you wrote:
OK, I think I understand now what you're aiming at: you want ublas to give you the characteristics of (ordinary ;-) runtime polymorphism. But would you be willing to pay the performance penalty for using an virtual operator() then, for example?
I think generally not. Hmmm, but is there a way to do without? After a lot of reading and thinking and with your help :-) I came out with the following. May I show you a code snippet from my spline function to show you my actual problem? =============================================================== template<class T> class vector_proxy_base { public: virtual T operator[] (unsigned int idx) = 0; };
template<class E> class vector_proxy : public vector_proxy_base<E::value_type> { public: vector_proxy(vector_expression<E> e) : m_e(e) {} typename E::value_type operator[] (unsigned int idx) { return m_e().operator[](idx); } private: vector_expression<E> m_e; };
template<class T> class spline : public std::unary_function<T, T> { public: template<class E> spline(vector_expression<E> e) : ex(new vector_proxy<E>(e)) {} ~ppi0() { delete ex; } T operator() (const T& x){ // the spline interpolation algorithm goes here ... return ex->[0]; // do something useful ;-) // ugly, indirection and virtual function call } private: vector_proxy_base<T>* ex; }; ===============================================================
I can not see a way to do this differently, since otherwise I would need to template<class T, class E> class spline { .... }
where E is the expression type.
Yep. Here it goes: ---------- #include <boost/numeric/ublas/vector.hpp> using namespace boost::numeric::ublas; template<class T, class E> class spline : public std::unary_function<T, T> { public: spline(const vector_expression<E> &e) : e_ (e) {} T operator() (const T& x){ // the spline interpolation algorithm goes here ... return e_ (0); // do something useful ;-) } private: const vector_expression<E> &e_; }; int main() { vector<double> v(3); spline<double, vector<double> > s1(v); // With GCC's extensions the following works :-) spline<double, typeof (v) > s2(v); } ----------
But instantiating the functor then would be infeasible since I do not know the complete expression hierarchy, or at least it is too cumbersome to specify.
This is a limitation of the language ;-/
The automatic template parameter deduction does not work for class templates as it does for funtion templates, does it?
What yet is missing of course are all the other member functions that make a vector or matrix.
Perhaps there is a simpler solution I do not see?
Not one that I know of.
vector_reference<> is mainly needed to describe the signatures of operators returning expression templates.
I was trying to template<class E> void foo(vector_reference<E> e) { e.size(); // some use of e }
and call it foo(m.column(0));
But my compiler chokes. So am I right, that vector_reference is not intended for this kind of usage?
Correct.
groups.yahoo.com/group/ublas-dev
Oh, I may read this as an ordinary user?
Maybe as an ordinary user you simply should copy the vector expression into another vector ;-) Regards, Joerg

Hi Joerg,
Yep. Here it goes: ---------- #include <boost/numeric/ublas/vector.hpp> using namespace boost::numeric::ublas; template<class T, class E> class spline : public std::unary_function<T, T> { public: spline(const vector_expression<E> &e) : e_ (e) {} T operator() (const T& x){ // the spline interpolation algorithm goes here ... return e_ (0); // do something useful ;-) } private: const vector_expression<E> &e_; }; int main() { vector<double> v(3); spline<double, vector<double> > s1(v); // With GCC's extensions the following works :-) spline<double, typeof (v) > s2(v); }
----------
Exactly. This is what I was thinking of. But as I understand now it probably is not such a good idea to keep a reference to an expression at all. Wouldn't it be reevaluated every time I "arg().(i,j)" i.e?
Maybe as an ordinary user you simply should copy the vector
expression into
another vector ;-)
I was thinking of this already. But now as I know my options and have a better idea what is going on behind the scenes I am much more comfortable with this. :-) So I most certainly will end up like that: void foo(vector<double> arg) { } matrix<double> m(3,3); vector<double> v(3); foo(m.row(0)); foo(v); And the converting constructor will create my temporary, which I do need anyway, as I can understand now. And when I really need to keep a reference to my data (or need to pass a really huge vector): template<class T> void foo(const vector<T>& arg) { } template<class E> void foo(vector_expression<E> arg) { foo(vector<E::value_type>(arg)); } I can have the above overloads and call the same function with an expression too. The more I understand the uBLAS, the more I like it. You have really done a good job! ( At least this is my opinion from user-land. :-) Thank you again! Roland
participants (2)
-
jhr.walter@t-online.de
-
speedsnaii <speedsnaii@yahoo.de>