mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
add specialization of check_sparse_solving() for SuperLU solver, in order to test adjoint and transpose solves
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
b578930657
commit
984d010b7b
@@ -156,6 +156,9 @@ class MappedSuperNodalMatrix
|
||||
class InnerIterator;
|
||||
template<typename Dest>
|
||||
void solveInPlace( MatrixBase<Dest>&X) const;
|
||||
template<bool Conjugate, typename Dest>
|
||||
void solveTransposedInPlace( MatrixBase<Dest>&X) const;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -294,6 +297,77 @@ void MappedSuperNodalMatrix<Scalar,Index_>::solveInPlace( MatrixBase<Dest>&X) co
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Scalar, typename Index_>
|
||||
template<bool Conjugate, typename Dest>
|
||||
void MappedSuperNodalMatrix<Scalar,Index_>::solveTransposedInPlace( MatrixBase<Dest>&X) const
|
||||
{
|
||||
using numext::conj;
|
||||
Index n = int(X.rows());
|
||||
Index nrhs = Index(X.cols());
|
||||
const Scalar * Lval = valuePtr(); // Nonzero values
|
||||
Matrix<Scalar,Dynamic,Dest::ColsAtCompileTime, ColMajor> work(n, nrhs); // working vector
|
||||
work.setZero();
|
||||
for (Index k = nsuper(); k >= 0; k--)
|
||||
{
|
||||
Index fsupc = supToCol()[k]; // First column of the current supernode
|
||||
Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column
|
||||
Index nsupr = rowIndexPtr()[fsupc+1] - istart; // Number of rows in the current supernode
|
||||
Index nsupc = supToCol()[k+1] - fsupc; // Number of columns in the current supernode
|
||||
Index nrow = nsupr - nsupc; // Number of rows in the non-diagonal part of the supernode
|
||||
Index irow; //Current index row
|
||||
|
||||
if (nsupc == 1 )
|
||||
{
|
||||
for (Index j = 0; j < nrhs; j++)
|
||||
{
|
||||
InnerIterator it(*this, fsupc);
|
||||
++it; // Skip the diagonal element
|
||||
for (; it; ++it)
|
||||
{
|
||||
irow = it.row();
|
||||
X(fsupc,j) -= X(irow, j) * (Conjugate?conj(it.value()):it.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The supernode has more than one column
|
||||
Index luptr = colIndexPtr()[fsupc];
|
||||
Index lda = colIndexPtr()[fsupc+1] - luptr;
|
||||
|
||||
//Begin Gather
|
||||
for (Index j = 0; j < nrhs; j++)
|
||||
{
|
||||
Index iptr = istart + nsupc;
|
||||
for (Index i = 0; i < nrow; i++)
|
||||
{
|
||||
irow = rowIndex()[iptr];
|
||||
work.topRows(nrow)(i,j)= X(irow,j); // Gather operation
|
||||
iptr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Matrix-vector product with transposed submatrix
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > A( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dest::ColsAtCompileTime, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
if(Conjugate)
|
||||
U = U - A.adjoint() * work.topRows(nrow);
|
||||
else
|
||||
U = U - A.transpose() * work.topRows(nrow);
|
||||
|
||||
// Triangular solve (of transposed diagonal block)
|
||||
new (&A) Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > ( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
if(Conjugate)
|
||||
U = A.adjoint().template triangularView<UnitUpper>().solve(U);
|
||||
else
|
||||
U = A.transpose().template triangularView<UnitUpper>().solve(U);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
Reference in New Issue
Block a user