Dear ublas developers!
(I am using boost 1.30 & gcc 3.2)
the following program:
#include
Hi Stephan, you wrote:
(I am using boost 1.30 & gcc 3.2)
the following program:
#include
#include int main () { using namespace boost::numeric::ublas; matrix<double> m (4, 4); for (unsigned int i = 0; i < m.size1 (); ++ i) for (unsigned int j = 0; j < m.size2 (); ++ j) m(i, j) = 1;
std::cout << m << std::endl;
// multiply a slice of the matrix with 2.... project (m, slice (2, 1, m.size1()-2), slice (1, 0, m.size1()-2)) *= 2;
// interesting result ... the slice has been multiplied with 4 std::cout << m << std::endl; }
gives the following output:
[4,4]((1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)) [4,4]((1,1,1,1),(1,1,1,1),(1,4,1,1),(1,4,1,1))
Why is the slice multiplied with 4 and not with 2?? Do I make some fundamental mistake?
The second slice 'slice (1, 0, m.size1()-2)' is degenerate in specifying a stride of 0, but a size of 2. With the modification // multiply a slice of the matrix with 2.... // project (m, slice (2, 1, m.size1()-2), slice (1, 0, m.size1()-2)) *= 2; project (m, slice (2, 1, m.size1()-2), slice (1, 0, 1)) *= 2; I get the result [4,4]((1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)) [4,4]((1,1,1,1),(1,1,1,1),(1,2,1,1),(1,2,1,1)) which is what I'd expect.
Everything works fine if I am using a matrix_vector_slice.
My second (stupid?)
Nope ;-)
question is the following: Is it intentional, that it is not possible to compile:
#include
#include int main () { using namespace boost::numeric::ublas; matrix<double> m (4, 4); for (unsigned int i = 0; i < m.size1 (); ++ i) for (unsigned int j = 0; j < m.size2 (); ++ j) m(i, j) = 4*i+j;
std::cout << m << std::endl;
swap(row(m,0), row(m,2));
std::cout << m << std::endl; }
No. This one compiles with ICC 7.0 and fails with GCC 3.2.1. I'll investigate that later.
whereas
matrix_row
l(m, 0); matrix_row r(m, 2); swap(l, r); /* swap the rows */
works fine.
Interesting. Thanks for your feedback, Joerg
Hi Joerg, hi Stephan,
question is the following: Is it intentional, that it is not possible to compile:
#include
#include int main () { using namespace boost::numeric::ublas; matrix<double> m (4, 4); for (unsigned int i = 0; i < m.size1 (); ++ i) for (unsigned int j = 0; j < m.size2 (); ++ j) m(i, j) = 4*i+j;
std::cout << m << std::endl;
swap(row(m,0), row(m,2));
std::cout << m << std::endl; }
No. This one compiles with ICC 7.0 and fails with GCC 3.2.1.
It also fails with como. As it should. This is the old problem of binding references to temporaries: parameters of `swap()' are *non-const* references, and they cannot be bound to temporaries returned by `row()'. It seems that `project()' raises its ugly head again :o( fres
Hi Joerg, Hi Fres! Thanks for the explanations!
This is the old problem of binding references to temporaries: parameters of `swap()' are *non-const* references, and they cannot be bound to temporaries returned by `row()'.
I only came up with this idea, because a similar (but not identical) syntax is valid in the MTL. I will perhaps just for fun try to dig into their sourcecode to see how they do trick, how they avoid the temporaries and what price they pay for being able to do it. Thanks for the help, ublas is great! Stephan ----------------------------------------------------------- Stephan Puchegger Email: Stephan.Puchegger@ap.univie.ac.at
Hi Joerg, Hi Fres! Thanks for the explanations!
This is the old problem of binding references to temporaries: parameters of `swap()' are *non-const* references, and they cannot be bound to temporaries returned by `row()'.
I only came up with this idea, because a similar (but not identical) syntax is valid in the MTL. I will perhaps just for fun try to dig into their sourcecode to see how they do trick, how they avoid the temporaries and what price they pay for being able to do it. Thanks for the help, ublas is great! Stephan ----------------------------------------------------------- Stephan Puchegger Email: Stephan.Puchegger@ap.univie.ac.at
Hi Kresimir, you wrote:
question is the following: Is it intentional, that it is not possible to compile:
#include
#include int main () { using namespace boost::numeric::ublas; matrix<double> m (4, 4); for (unsigned int i = 0; i < m.size1 (); ++ i) for (unsigned int j = 0; j < m.size2 (); ++ j) m(i, j) = 4*i+j;
std::cout << m << std::endl;
swap(row(m,0), row(m,2));
std::cout << m << std::endl; }
No. This one compiles with ICC 7.0 and fails with GCC 3.2.1.
It also fails with como. As it should.
Thanks for checking that!
This is the old problem of binding references to temporaries: parameters of `swap()' are *non-const* references, and they cannot be bound to temporaries returned by `row()'.
It seems that `project()' raises its ugly head again :o(
Not sure about that. Maybe swap()'s signatures are inadequate for the view
classes. If I change matrix_row<>'s swap() member signatures from
void swap (matrix_row &mr);
friend void swap (matrix_row &mr1, matrix_row &mr2);
to
void swap (matrix_row mr);
friend void swap (matrix_row mr1, matrix_row mr2);
the following test program compiles on GCC 3.2.1 and Intel 7.0:
----------
#include
Hej Joerg! Your changes are very welcome! The new code does require far less local variables and is much more compact on the user side. Correct me if I am wrong (I did not dig into the internals of ublas), but does not swap() rather change the matrix itself and not the matrix_row representations? If this is the case, then the whole topic of "not changing temporaries in not-const references" is of course true, but does not reflect the situation, since not the temporaries, but the matrix, on which the temporaries rely, is changed. Then the new signatures do reflect the situation much better. Best regards and thanks for your great work! Stephan ----------------------------------------------------------- Stephan Puchegger Email: Stephan.Puchegger@ap.univie.ac.at -----------------------------------------------------------
Hi Stephan, you wrote:
Your changes are very welcome! The new code does require far less local variables and is much more compact on the user side.
Correct me if I am wrong (I did not dig into the internals of ublas), but does not swap() rather change the matrix itself and not the matrix_row representations?
Exactly.
If this is the case, then the whole topic of "not changing temporaries in not-const references" is of course true, but does not reflect the situation, since not the temporaries, but the matrix, on which the temporaries rely, is changed. Then the new signatures do reflect the situation much better.
But nevertheless it's pretty surprising, that one needs to swap these 'by value' ;-) Best, Joerg P.S.: New download is available at groups.yahoo.com/group/ublas-dev/files/ublas_2003_04_08.zip P.P.S.: Basically regression tested.
participants (3)
-
jhr.walter@t-online.de
-
Kresimir Fresl
-
Stephan Puchegger