Re: another quick question
Sven Olsen <[email protected]> Wed, 03 Dec 2003 09:06:05 -0500
| Newsgroups | gmane.comp.lib.mtl.devel |
|---|---|
| Message-ID | <[email protected]> |
Thanks Rich,
Your code was very helpful, though MSVC6 has some issues with it.
More exactly, it considers
Matrix::OneD A0 = A[i];
To be an assignment between incompatible types.
Using Matrix::OneDRef instead of Matrix::OneD gets rid of the compiler
error, but simply substituting OneDRef's into your code leads to the same
old crash.
I've failed to find a simple modification of your swap_row function which
will work under MSVC6, but I have figured out how to do the swap "by hand";
which ought to be good enough given my limited purposes.
-Sven
struct dn {
double d;
int n;
dn(double d, int n) : d(d), n(n) {}
};
//much slower than it needs to be, but still potentially faster than using
dense matrices...
void swap_row(Matrix& A, int i, int j) {
std::vector<dn> A0;
std::vector<dn> A1;
Matrix::OneDRef::iterator r;
for(r=A[i].begin();r!=A[i].end();r++)
A0.push_back(dn(*r,r.index()));
for(r=A[j].begin();r!=A[j].end();r++)
A1.push_back(dn(*r,r.index()));
A[i].clear();
A[j].clear();
std::vector<dn>::iterator s;
for(s=A0.begin();s!=A0.end();s++)
A[j].push_back(s->n,s->d);
for(s=A1.begin();s!=A1.end();s++)
A[i].push_back(s->n,s->d);
}
At 10:27 PM 12/2/2003 -0800, liequan wrote:
>Hi Sven,
>
>The following code compiles and runs correctly wiht gcc 3.3 for swapping
>two rows in array compressed1D matrix. It is not constant time though.
>
>#include "mtl/matrix.h"
>#include "mtl/mtl.h"
>#include "mtl/utils.h"
>#include <algorithm>
>
>using namespace mtl;
>
>typedef matrix< double, rectangle<>, array< compressed<> >,
>row_major >::type Matrix;
>
>void
>swap_row(Matrix& A, int i, int j)
>{
> Matrix::OneD A0 = A[i];
> Matrix::OneD A1 = A[j];
> mtl::swap(A0, A1);
> typedef Matrix::OneD::size_type I;
> std::vector<I>& A0n = const_cast<std::vector<I>&>(A0.nz_struct());
> std::vector<I>& A1n = const_cast<std::vector<I>&>(A1.nz_struct());
> std::swap(A0n, A1n);
>}
>
>int main ()
>{
> //initialize the matrix
> const int size=4;
> Matrix A(size,size);
> A(0,0)=1;
> A(1,2)=2;
> A(3,1)=5;
> A(0,3)=3;
>
> swap_row(A, 0, 1);
>
> print_all_matrix(A);
> return 0;
>}
>
>Andy, I am sorry for misleading information -- I was wrong about
>swapping. In fact, only dense matrices/dense vectors are taken care by
>mtl::swap in mtl2.
>
>--Rich Lee
>
>
>On Tue, 2003-12-02 at 20:38, Sven Olsen wrote:
> > At 07:49 PM 12/2/2003 -0500, you wrote:
> > >I think this example code should swap the two rows in constant time.
> >
> > Hmm. Well, the example code I gave crashes in terrible ways... I assumed
> > it was breaking because I wasn't using the library properly, but if you
> > think it should work, then something is going wrong...
> >
> > I've done a little investigation, and it looks like the problems that I've
> > been running into with row swapping are most likely due to the fact that
> > the mtl::swap functions will swap the value vectors of two compressed
> > arrays, but not the index vectors (which leads to all sorts of interesting
> > problems).
> > I have started hacking around with a solution to use in my own code, but I
> > don't know my way around the MTL source, so even if I get something
> > working, it's probably not going to be pretty.
> >
> > From what I've seen, this is something that anyone who knew the MTL
> source
> > fairly well would have little trouble fixing.
> >
> > Here's the code that crashes in terrible ways:
> >
> > #include "mtl/matrix.h"
> > #include "mtl/mtl.h"
> > #include "mtl/utils.h"
> >
> > using namespace mtl;
> >
> > typedef matrix< double, rectangle<>, array< compressed<> >,
> > row_major >::type Matrix;
> >
> > int main ()
> > {
> > using std::cout;
> > using std::endl;
> >
> > //initialize the matrix
> > const int size=4;
> > Matrix A(size,size);
> > A(0,0)=1;
> > A(1,2)=2;
> > A(3,1)=5;
> > A(0,3)=3;
> >
> > //swap the first two rows
> > mtl::swap(A[0],A[1]);
> >
> > //output the results
> > for (int ii=0; ii<A.nrows(); ii++) {
> > for (int j=0; j<A.ncols(); j++) {
> > cout.width(6);
> > cout << A(ii, j) << " ";
> > }
> > cout << endl;
> > }
> >
> > return 0;
> > }
> >
> > The output that I get is:
> >
> > 2 0 0 2.10535e-314
> > 0 0 1 0
> > 0 0 0 0
> > 0 5 0 0
> >
> > I then crash while trying to execute the cleanup function "_free_dbg".
> >
> > A little more experimenting indicates that while I am swapping the value
> > vectors, I'm not swapping the index vectors-
> > So the matrix defined by
> > Matrix A(2,2);
> > A(0,0)=1;
> > A(1,2)=2;
> > Swaps rows without trouble (which makes sense because the index vectors
> are
> > the same for each row)
> >
> > While swapping the rows in
> > Matrix A(2,4);
> > A(0,0)=1;
> > A(1,2)=2;
> > A(1,1)=6;
> > A(0,3)=3;
> >
> > Yeilds
> > 6 0 0 2
> > 0 1 3 0
> >
> > when it clearly should give
> > 0 6 2 0
> > 1 0 0 3
> >
> > Thanks for your help,
> > Sven
> >
> >
> > >On Dec 2, 2003, at 5:31 PM, Sven Olsen wrote:
> > >
> > >>If I am working with a matrix of type:
> > >>
> > >>typedef matrix< double, rectangle<>, array< compressed<> >,
> > >>row_major >::type Matrix;
> > >>
> > >>what is the easiest way to swap two of the rows?
> > >>
> > >>I.E., I want to do something like
> > >>Matrix A(4,4);
> > >>/*initialize A*/
> > >>swap(A[0],A[1]);
> > >>
> > >>Thanks,
> > >> Sven
> > >>
> > >>_______________________________________________
> > >>This list is archived at http://www.osl.iu.edu/MailArchives/mtl-devel/
> > >
> > >_______________________________________________
> > >This list is archived at http://www.osl.iu.edu/MailArchives/mtl-devel/
> >
> > _______________________________________________
> > This list is archived at http://www.osl.iu.edu/MailArchives/mtl-devel/
_______________________________________________
This list is archived at http://www.osl.iu.edu/MailArchives/mtl-devel/