Solving a linear system with triangular matrix
I want to solve the system of equations A*x=b
, where A
is lower-triangular. I can use either the blas::trsv()
function or the inv()
expression:
blaze::LowerMatrix<blaze::DynamicMatrix<Real, blaze::columnMajor>> A(M, M);
blaze::DynamicVector<Real, blaze::columnVector> b(M);
blaze::DynamicVector<Real, blaze::columnVector> x(M);
randomize(A);
randomize(b);
bool const use_inv = true;
if (use_inv)
x = inv(A) * b;
else
{
x = b;
trsv(A, x, 'L', 'N', 'N');
}
- I noticed that for big
A
matrices theinv(A) * b
version results in a call to BLASdtrtri
function, i.e. the matrix is first inverted and then multiplied with a vector. This is less efficient than usingtrsv()
. I think it would be an improvement if Blaze could detect thatA
is aLowerMatrix
and usetrsv()
instead. - I see from the code that for small
A
Blaze uses custom inversion kernels. But still, it first invertsA
and then multiplies it withb
. - I could directly call
trsv()
, but I want to take the advantage of custom kernels for small matrices, which are, according to my benchmarks, significantly faster than calls to BLAS.
Would it be possible to make it such that when evaluating inv(A) * b
with triangular A
- for large matrices, BLAS
trsv()
is used, - for small matrices, solution is performed using optimized small kernels,
- no inversion of
A
is performed?
Best regards,
Misha
Comments (7)
-
-
-
assigned issue to
-
assigned issue to
-
- changed status to open
-
reporter Hello Klaus,
Is there an explicit way to tell Blaze to perform the substitution and not matrix inversion (besides using BLAS trsv wrapper)?
-
Hi Misha!
No, so far there is no way to explicitly perform a substitution (for instance in form of a
solve()
function). Your best option is to calltrsv()
explicitly.Best regards,
Klaus!
-
- changed status to resolved
The feature has been implemented, tested, optimized, and documented as required. The following four expressions are now handled by means of linear system solvers instead of inverting a matrix and a subsequent multiplication:
x = inv(A) * b;
wherex
andb
are dense column vectors andA
is a dense matrix;x = b * inv(A);
wherex
andb
are dense row vectors andA
is a dense matrix;X = inv(A) * B;
whereX
,B
, andA
are dense matrices;X = B * inv(A);
whereX
,B
, andA
are dense matrices.
The implementation adheres to the three given requirements:
- for large matrices, BLAS
trsv()
or faster approaches are used; - for small matrices, the solution is computed by using manually optimized kernels;
- no inversion of
A
is performed.
It is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.7.
-
reporter Great, thanks for the update!
- Log in to comment
Hi Misha!
You are absolutely correct, in this case there should be no inversion, but only the back substitution. If there is indeed an inversion happening then this is an oversight/defect on our side. We will fix this as soon as possible. Thanks a lot for pointing this out,
Best regards,
Klaus!