[Lapackpp-devel] bugs in operator= for LaIndex/LaGenMatComplex/LaGenMatDouble?
Status: Beta
Brought to you by:
cstim
From: Brian W. <bw...@cs...> - 2005-09-11 19:51:29
|
Hello, I think I've uncovered a few bugs. In LaIndex::oeprator=(const LaIndex &i), the following definition ignores the increment of the LaIndex it is copying: inline LaIndex& operator=(const LaIndex& i){ start_=i.start_; inc_=1; end_=i.end_; return *this;} I think inc_=1 should be inc_=i.inc_: inline LaIndex& operator=(const LaIndex& i){ start_=i.start_; inc_=i.inc_; end_=i.end_; return *this;} Also, LaGenMatComplex::operator=(COMPLEX s) and LaGenMatDouble::operator=(double s) seem to be problematic since both assign to the vectorDouble v without accounting for the active view of the LaGenMatDouble object. I believe this means that if we assign (via operator=) through a submatrix view, the entire matrix will be effected. So, instead of doing v = s; in both LaGenMatComplex::operator=(COMPLEX s) and LaGenMatDouble::operator=(double s), we should instead have: int i,j; for (j=0; j<size(1); j++) { for (i=0; i<size(0); i++) { (*this)(i,j) = s; } } and something similar for the complex case. Note that this mirrors operator+= (obviously, with += replaced by =). Below is some example code (taken essentially from the Lapack++ 1.1 manual when it was still being developed by NIST/Tennessee/Oak Ridge). I've included what I believe to be the correct output and also the output I get before making the above changes. By the way, this differs from the example in the manual only in so far as assignments are replaced by references. i.e., B = A(II,II) is replaced below by B.ref(A(II,II)). If I'm reading that manual correctly, B = A(II,II) should establish B as a reference to elements in A. Instead it appears to perform a (deep) copy. Thanks, Brian int main(int argc, char **argv) { LaGenMatDouble A(10,10), B, C; LaIndex II(1,9,2); LaIndex JJ(1,1,1); B.ref(A(II,II)); // B references the following elements of A: // (1, 1), (1, 3), (1, 5), (1, 7), (1, 9) // (3, 1), (3, 3), (3, 5), (3, 7), (3, 9) // (5, 1), (5, 3), (5, 5), (5, 7), (5, 9) // (7, 1), (7, 3), (7, 5), (7, 7), (7, 9) // (9, 1), (9, 3), (9, 5), (9, 7), (9, 9) B(2,3) = 3.1; // Set A(5,7) = 3.1 C.ref(B(LaIndex(2,2,4), JJ)); // C references the following elements of B: // (2, 1) // C references the following elements of A: // (5, 3) C = 1.1; // Set B(2,1) = A(5,3) = 1.1 cout << A << endl; cout << B << endl; cout << C << endl; return 0; } Correct output: 0 0 0 0 0 0 0 0 0 0 7.94687e-311 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.1 0 0 0 3.1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // Note the following matrix is 5x5 0 0 0 0 0 0 0 0 0 0 0 1.1 0 3.1 0 0 0 0 0 0 0 0 0 0 0 1.1 Incorrect output: 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 // The following matrix is 9x9 because the // view (II=(1,9,2),II) is incorrectly copied to // (I=(1,9,1),I) when the increment is set to 1 // irrespective of the LaIndex being copied. // Also, we have assigned to the entire matrix, // rather than simply the view specified in // C.ref(B(LaIndex(2,2,4), JJ)); 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 |