CompressedMatrix changes when accessed

Issue #76 resolved
R L created an issue

Hi,

When I read a CompressedMatrix twice consecutively for debugging, the first time i obtain the correct values and the second time I obtain different values,

for (jj = 1;jj < 54;jj++) { for (i = 1;i <= nodes;i++) { Array[i - 1][i - 1] = CompMat(i - 1, i - 1).get();

for (k = ij_index[i];k <= ij_index[i + 1] - 1;k++) { j = ij_index[k];
    Array[i - 1][j - 1] = CompMat(i - 1, j - 1).get();  }

} }

Could you please tell me why the compressedmatrix changes,

Thank you for your help,

Comments (9)

  1. Klaus Iglberger

    Hi Raounak!

    We cannot reproduce the problem that you describe. For instance, the sample code below traverses the matrix twice and reads it into two different arrays. After the second traversal, both arrays contain exactly the same values:

    // Creating a random compressed matrix
    CompressedMatrix<int,rowMajor> A( 5UL, 5UL );
    randomize( A );
    
    // Reading from the matrix the first time
    int array1[5][5];
    
    for( size_t i=0UL; i<5UL; ++i ) {
       for( size_t j=0UL; j<5UL; ++j ) {
          array1[i][j] = A(i,j);
       }
    }
    
    // Reading from the matrix the second time
    int array2[5][5];
    
    for( size_t i=0UL; i<5UL; ++i ) {
       for( size_t j=0UL; j<5UL; ++j ) {
          array2[i][j] = A(i,j);
       }
    }
    
    // Looking for a difference in the two arrays
    for( size_t i=0UL; i<5UL; ++i ) {
       for( size_t j=0UL; j<5UL; ++j ) {
          if( array1[i][j] != array2[i][j] )
             std::cerr << " Difference at (" << i << "," << j << ") detected!\n";
       }
    }
    

    We suspect that your program contains an error in the indexing. Therefore, as a first step to find the issue, could you also please run in debug mode (i.e. not define -DNDEBUG) on the command line and enable both internal and user assertions in blaze/config/Assertion.h? You should get an assertion in case you have an out-of-bound access. Alternatively, you could use the at() function instead of the subscript operator to access the values of the matrix. In this case an out-of-bound access would trigger an exception. This should help to find potential indexing errors. If this doesn't help, could you please provide us with a minimum example that demonstrates the problem, including the exact type of the matrix and the way you traverse the matrix?

    Best regards,

    Klaus!

  2. R L reporter

    Hi Klaus,

    Thank you very much for your response,

    After many tests, I discovered that the "=" operator transforms the small values (under 1E-8) into zero, whereas the set() function can store this kind of values:

    double Precision=1;
    // Creating a random compressed matrix
    CompressedMatrix<double, rowMajor> A(5UL, 5UL), B(5UL, 5UL);
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            Precision /= 10;
            A(i, j)=Precision;
            B.set(i, j, Precision);
        }
    }
    // Reading from the matrix the first time
    double array1[5][5];
    
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            array1[i][j] = A(i, j);
        }
    }
    
    // Reading from the matrix the second time
    double array2[5][5];
    
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            array2[i][j] = A(i, j);
        }
    }
    
    // Looking for a difference in the two arrays
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            if (array1[i][j] != array2[i][j])
                std::cerr << " Difference at (" << i << "," << j << ") detected!\n";
        }
    }
    
    // Reading from the matrix the first time
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            array1[i][j] = B(i, j);
        }
    }
    
    // Reading from the matrix the second time
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            array2[i][j] = B(i, j);
        }
    }
    
    // Looking for a difference in the two arrays
    for (size_t i = 0UL; i<5UL; ++i) {
        for (size_t j = 0UL; j<5UL; ++j) {
            if (array1[i][j] != array2[i][j])
                std::cerr << " Difference at (" << i << "," << j << ") detected!\n";
        }
    }
    

    Do you know how to disactivate this lower limit?

    Thank you very mych,

    Best regards,

    Raounak

  3. Klaus Iglberger

    Hi Raounak!

    Thanks for your feedback. You are correct, in Blaze 3.0 there is indeed a discrepancy between operator=() and the set()/insert() functions. The latter allow you to insert any value, whereas the former filters out values close to zero. Since this behavior is unexpected, we have planned to fix this in Blaze 3.1: Both operator=() and the set()/insert() functions should allow to add close-to-zero values and only filter out values that are exactly zero. We have made the according changes available for you, so all you have to do is to clone the latest development version from the repository. We hope this solves your problem.

    Allow us to point out that using the subscript operator on a sparse vector or matrix always involves a search operation for the according element. Therefore if you want to traverse the non-zero elements of a sparse matrix, it is recommended to prefer iterators (see the wiki).

    Best regards,

    Klaus!

  4. Klaus Iglberger

    The fix has been implemented and tested as required. It is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.1.

  5. R L reporter

    Hi Klaus!

    Thank you very much,

    It works now,

    I do FEM, and I filled directly the global matrix in the CompressedMatrix without considering the order of rows and columns. Now, I will construct the matrix in an array and fill the CompressedMatrix all at once and in increasing order so as to optimize the storing time.

    Thank you again,

    Raounak

  6. Log in to comment