Skip to content

Commit f6b8ab1

Browse files
committed
Condition number estimation for custom LDLTs
1 parent b658c33 commit f6b8ab1

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

include/albatross/src/eigen/serializable_ldlt.hpp

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ namespace Eigen {
1818
// See LDLT.h in Eigen for a detailed description of the decomposition
1919
class SerializableLDLT : public LDLT<MatrixXd, Lower> {
2020
public:
21+
using RealScalar = double;
22+
using Scalar = double;
23+
using MatrixType = MatrixXd;
24+
2125
SerializableLDLT() : LDLT<MatrixXd, Lower>(){};
2226

2327
SerializableLDLT(const MatrixXd &x) : LDLT<MatrixXd, Lower>(x.ldlt()){};
@@ -43,6 +47,11 @@ class SerializableLDLT : public LDLT<MatrixXd, Lower> {
4347

4448
bool is_initialized() const { return this->m_isInitialized; }
4549

50+
double l1_norm() const {
51+
ALBATROSS_ASSERT(is_initialized() && "Must initialize first!");
52+
return this->m_l1_norm;
53+
}
54+
4655
/*
4756
* Computes the inverse of the square root of the diagonal, D^{-1/2}
4857
*/

include/albatross/src/linalg/block_diagonal.hpp

+22
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ struct BlockDiagonalLDLT;
2222
struct BlockDiagonal;
2323

2424
struct BlockDiagonalLDLT {
25+
using RealScalar = Eigen::SerializableLDLT::RealScalar;
26+
using Scalar = Eigen::SerializableLDLT::Scalar;
27+
using MatrixType = Eigen::SerializableLDLT::MatrixType;
2528
std::vector<Eigen::SerializableLDLT> blocks;
2629

2730
template <class _Scalar, int _Rows, int _Cols>
@@ -50,10 +53,14 @@ struct BlockDiagonalLDLT {
5053
sqrt_solve(const Eigen::Matrix<_Scalar, _Rows, _Cols> &rhs,
5154
ThreadPool *pool) const;
5255

56+
const BlockDiagonalLDLT &adjoint() const;
57+
5358
std::map<size_t, Eigen::Index> block_to_row_map() const;
5459

5560
double log_determinant() const;
5661

62+
double rcond() const;
63+
5764
Eigen::Index rows() const;
5865

5966
Eigen::Index cols() const;
@@ -197,6 +204,17 @@ inline double BlockDiagonalLDLT::log_determinant() const {
197204
return output;
198205
}
199206

207+
inline double BlockDiagonalLDLT::rcond() const {
208+
// L1 induced norm is just the maximum absolute column sum.
209+
// Therefore the L1 induced norm of a block-diagonal matrix is the
210+
// maximum of the L1 induced norms of the individual blocks.
211+
double l1_norm = -INFINITY;
212+
for (const auto &b : blocks) {
213+
l1_norm = std::max(l1_norm, b.l1_norm());
214+
}
215+
return Eigen::internal::rcond_estimate_helper(l1_norm, *this);
216+
}
217+
200218
inline Eigen::Index BlockDiagonalLDLT::rows() const {
201219
Eigen::Index n = 0;
202220
for (const auto &b : blocks) {
@@ -213,6 +231,10 @@ inline Eigen::Index BlockDiagonalLDLT::cols() const {
213231
return n;
214232
}
215233

234+
inline const BlockDiagonalLDLT &BlockDiagonalLDLT::adjoint() const {
235+
return *this;
236+
}
237+
216238
/*
217239
* Block Diagonal
218240
*/

0 commit comments

Comments
 (0)