How to get a strictly lower matrix L from a given general matrix A, which is not a strictly lower matrix

Issue #265 duplicate
nanmiao wu created an issue

I am trying to get a strictly lower matrix L from a given general matrix A. Since A is not a strictly lower matrix and triangular property is always enforced, I cannot directly construct L from A or assign A to L.

One possible solution is to use blaze::band function. But band function can only use one specific band each time. If I want to use the band from -1L to -(m-1)L, where m is the dimension of matrix A. How can I get the strictly lower matrix L from the matrix A without using a for loop?

Comments (9)

  1. Klaus Iglberger

    Hi!

    From your description I understand that the general matrix A is not strictly lower and that you want to extract the (strictly) lower part of A. This feature unfortunately hasn’t been implemented yet, but is planned (see issue #26). For now you will have to copy explicitly by means of for loops.

    The following code example gives an impression how to do this copy operation without any performance penalties due to runtime checks in the strictly lower target matrix:

    template< typename MT1, bool SO1, typename MT2, bool SO2 >
    void copyStrictlyLowerPart( const DenseMatrix<MT1,SO1>& src, DenseMatrix<MT2,SO2>& dst )
    {
       decltype(auto) target( derestrict( ~dst ) );
    
       for( size_t i=1UL; i<(~src).rows(); ++i ) {
          for( size_t j=0UL; j<i; ++j ) {
             (~target)(i,j) = (~src)(i,j);
          }
       }
    }
    

    I hope this helps. Thanks for creating this issue,

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Hi!

    I’m sorry, I just realized I provided you with the wrong issue number. Issue #29 is about integrating lower and upper matrix views. Again, I apologize for the mixup.

    I’ll will close this issue as a duplicate in favour of issue #29. Thanks again,

    Best regards,

    Klaus!

  3. nanmiao wu reporter

    Hi Klaus,

    I tried to run the code. But it did not work. First of all, I did not find a matrix type named “DenseMatrix“, so I change all DenseMatrix to DynamicMatrix.

    Then it is shown:

  4. Klaus Iglberger

    Hi!

    I implicitly use an using namespace blaze; before the code. Please replace all DenseMatrix by blaze::DenseMatrix:

    template< typename MT1, bool SO1, typename MT2, bool SO2 >
    void copyStrictlyLowerPart( const blaze::DenseMatrix<MT1,SO1>& src, blaze::DenseMatrix<MT2,SO2>& dst )
    {
       decltype(auto) target( derestrict( ~dst ) );
    
       for( size_t i=1UL; i<(~src).rows(); ++i ) {
          for( size_t j=0UL; j<i; ++j ) {
             (~target)(i,j) = (~src)(i,j);
          }
       }
    }
    

    Best regards,

    Klaus!

  5. nanmiao wu reporter

    Hi Klaus,

    Thanks for the reply. But blaze::DenseMatrix is not the issue.

    Since matrix A in my code is in the form of:

    template< typename MatrixType>

    void function_name( ..., const MatrixType& A, ... ),

    I change the code you showed me to make them match, as:

    template< typename MatrixType>

    void copyStrictlyLowerPart( const MatrixType& src, MatrixType& dst )

    {

    the same

    }

    But it does not work, shown as:

    Do you have any idea about the error information and what I can do?

    Thanks!

  6. Klaus Iglberger

    Hi!

    From the given information I can only take a wild guess. Do the two matrices have the same dimensions? In the function it is assumed that both matrices have the same size and that dst is already initialized. Else you would have to resize and initialize the target matrix manually:

    template< typename MT1, bool SO1, typename MT2, bool SO2 >
    void copyStrictlyLowerPart( const blaze::DenseMatrix<MT1,SO1>& src, blaze::DenseMatrix<MT2,SO2>& dst )
    {
       decltype(auto) target( derestrict( ~dst ) );
       resize( target, (~src).rows(), (~src).columns() );
       reset( target );
    
       for( size_t i=1UL; i<(~src).rows(); ++i ) {
          for( size_t j=0UL; j<i; ++j ) {
             (~target)(i,j) = (~src)(i,j);
          }
       }
    }
    

    That’s unfortunately the only idea I have. I hope this help,

    Best regards,

    Klaus!

  7. nanmiao wu reporter

    Hi Klaus,

    You are right. I forget to declare the size of dst matrix before passing it to the copyStrictlyLowerPart function. It works correct now! Thank you so much!

    Best regards,

    Nanmiao

  8. Log in to comment