23 #include <gtsam/dllexport.h> 24 #include <boost/serialization/nvp.hpp> 30 namespace serialization {
38 class VerticalBlockMatrix;
55 typedef Eigen::Block<Matrix> Block;
56 typedef Eigen::Block<const Matrix> constBlock;
69 variableColOffsets_.push_back(0);
74 template<
typename CONTAINER>
78 fillOffsets(dimensions.begin(), dimensions.end(), appendOneDimension);
79 matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
84 template<
typename ITERATOR>
88 fillOffsets(firstBlockDim, lastBlockDim, appendOneDimension);
89 matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
94 template<
typename CONTAINER>
98 matrix_.resize(matrix.rows(), matrix.cols());
99 matrix_.triangularView<Eigen::Upper>() = matrix.triangularView<Eigen::Upper>();
100 fillOffsets(dimensions.begin(), dimensions.end(), appendOneDimension);
101 if(matrix_.rows() != matrix_.cols())
102 throw std::invalid_argument(
"Requested to create a SymmetricBlockMatrix from a non-square matrix.");
103 if(variableColOffsets_.back() != matrix_.cols())
104 throw std::invalid_argument(
"Requested to create a SymmetricBlockMatrix with dimensions that do not sum to the total size of the provided matrix.");
119 DenseIndex rows()
const { assertInvariants();
return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
129 return calcIndices(block, block, 1, 1)[2];
141 return block_(J, J).selfadjointView<Eigen::Upper>();
146 return block_(J, J).selfadjointView<Eigen::Upper>();
151 return block_(J, J).diagonal();
164 return block_(I, I, J - I, J - I).selfadjointView<Eigen::Upper>();
171 return block_(I, I, J - I, J - I).triangularView<Eigen::Upper>();
179 assert(i_startBlock < j_startBlock);
180 assert(i_endBlock <= j_startBlock);
181 return block_(i_startBlock, j_startBlock, i_endBlock - i_startBlock,
182 j_endBlock - j_startBlock);
188 assert(i_startBlock < j_startBlock);
189 assert(i_endBlock <= j_startBlock);
190 return block_(i_startBlock, j_startBlock, i_endBlock - i_startBlock,
191 j_endBlock - j_startBlock);
199 template <
typename XprType>
201 block_(I, I).triangularView<Eigen::Upper>() = xpr.template triangularView<Eigen::Upper>();
205 template <
typename XprType>
211 block_(J, I) = xpr.transpose();
216 template <
typename XprType>
220 auto dest = block_(I, I);
221 assert(dest.rows() == xpr.rows());
222 assert(dest.cols() == xpr.cols());
223 for (
DenseIndex col = 0; col < dest.cols(); ++col) {
225 dest(
row, col) += xpr(
row, col);
232 template <
typename XprType>
236 block_(I, J).noalias() += xpr;
238 block_(J, I).noalias() += xpr.transpose();
248 return full().selfadjointView<Eigen::Upper>();
253 return full().selfadjointView<Eigen::Upper>();
257 template <
typename XprType>
259 full().triangularView<Eigen::Upper>() = xpr.template triangularView<Eigen::Upper>();
264 full().triangularView<Eigen::Upper>().setZero();
269 full().triangularView<Eigen::Upper>() *= -1.0;
274 const auto identity = Matrix::Identity(rows(), rows());
275 full().triangularView<Eigen::Upper>() =
279 .triangularView<Eigen::Upper>();
316 return variableColOffsets_.size();
321 return nOffsets() - 1;
327 const DenseIndex actual_index = block + blockStart();
328 assert(actual_index < nOffsets());
329 return variableColOffsets_[actual_index];
335 const std::array<DenseIndex, 4> indices =
336 calcIndices(iBlock, jBlock, blockRows, blockCols);
337 return matrix_.block(indices[0], indices[1], indices[2], indices[3]);
343 const std::array<DenseIndex, 4> indices =
344 calcIndices(iBlock, jBlock, blockRows, blockCols);
345 return matrix_.block(indices[0], indices[1], indices[2], indices[3]);
350 return block_(0, 0, nBlocks(), nBlocks());
355 return block_(0, 0, nBlocks(), nBlocks());
362 assert(blockRows >= 0);
363 assert(blockCols >= 0);
368 const DenseIndex denseRows = offset(iBlock + blockRows) - denseI;
369 const DenseIndex denseCols = offset(jBlock + blockCols) - denseJ;
370 return {{denseI, denseJ, denseRows, denseCols}};
373 void assertInvariants()
const 375 assert(matrix_.rows() == matrix_.cols());
376 assert(matrix_.cols() == variableColOffsets_.back());
377 assert(blockStart_ < (
DenseIndex)variableColOffsets_.size());
380 template<
typename ITERATOR>
381 void fillOffsets(ITERATOR firstBlockDim, ITERATOR lastBlockDim,
bool appendOneDimension)
383 variableColOffsets_.resize((lastBlockDim-firstBlockDim) + 1 + (appendOneDimension ? 1 : 0));
384 variableColOffsets_[0] = 0;
386 for(ITERATOR dim=firstBlockDim; dim!=lastBlockDim; ++dim) {
387 variableColOffsets_[j+1] = variableColOffsets_[j] + *dim;
390 if(appendOneDimension)
392 variableColOffsets_[j+1] = variableColOffsets_[j] + 1;
397 friend class VerticalBlockMatrix;
398 template<
typename SymmetricBlockMatrixType>
friend class SymmetricBlockMatrixBlockExpr;
402 friend class boost::serialization::access;
403 template<
class ARCHIVE>
404 void serialize(ARCHIVE & ar,
const unsigned int ) {
408 matrix_.triangularView<Eigen::Lower>() = matrix_.triangularView<Eigen::Upper>().transpose();
409 ar & BOOST_SERIALIZATION_NVP(matrix_);
410 ar & BOOST_SERIALIZATION_NVP(variableColOffsets_);
411 ar & BOOST_SERIALIZATION_NVP(blockStart_);
416 class CholeskyFailed;
DenseIndex getDim(DenseIndex block) const
Number of dimensions for variable on this diagonal block.
Definition: SymmetricBlockMatrix.h:128
constBlock aboveDiagonalBlock(DenseIndex I, DenseIndex J) const
Get block above the diagonal (I, J).
Definition: SymmetricBlockMatrix.h:155
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:63
A thin wrapper around std::vector that uses a custom allocator.
DenseIndex cols() const
Column size.
Definition: SymmetricBlockMatrix.h:122
FastVector< DenseIndex > variableColOffsets_
the starting columns of each block (0-based)
Definition: SymmetricBlockMatrix.h:60
Block full()
Get the full matrix as a block.
Definition: SymmetricBlockMatrix.h:354
SymmetricBlockMatrix(const CONTAINER &dimensions, bool appendOneDimension=false)
Construct from a container of the sizes of each block.
Definition: SymmetricBlockMatrix.h:75
DenseIndex rows() const
Row size.
Definition: SymmetricBlockMatrix.h:119
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
Split the graph into two parts: one corresponds to the given spanning tree, and the other corresponds...
Definition: graph-inl.h:255
Eigen::SelfAdjointView< constBlock, Eigen::Upper > selfadjointView() const
Get self adjoint view.
Definition: SymmetricBlockMatrix.h:252
void setOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Set an off-diagonal block. Only the upper triangular portion of xpr is evaluated.
Definition: SymmetricBlockMatrix.h:206
constBlock block_(DenseIndex iBlock, DenseIndex jBlock, DenseIndex blockRows=1, DenseIndex blockCols=1) const
Get an arbitrary block from the matrix. Indices are in block units.
Definition: SymmetricBlockMatrix.h:333
DenseIndex offset(DenseIndex block) const
Get an offset for a block index (in the active view).
Definition: SymmetricBlockMatrix.h:325
Eigen::TriangularView< constBlock, Eigen::Upper > triangularView(DenseIndex I, DenseIndex J) const
Return the square sub-matrix that contains blocks(i:j, i:j) as a triangular view.
Definition: SymmetricBlockMatrix.h:168
Definition: VerticalBlockMatrix.h:41
Eigen::SelfAdjointView< constBlock, Eigen::Upper > selfadjointView(DenseIndex I, DenseIndex J) const
Return the square sub-matrix that contains blocks(i:j, i:j).
Definition: SymmetricBlockMatrix.h:161
void setDiagonalBlock(DenseIndex I, const XprType &xpr)
Set a diagonal block. Only the upper triangular portion of xpr is evaluated.
Definition: SymmetricBlockMatrix.h:200
SymmetricBlockMatrix()
Construct from an empty matrix (asserts that the matrix is empty)
Definition: SymmetricBlockMatrix.h:66
constBlock aboveDiagonalRange(DenseIndex i_startBlock, DenseIndex i_endBlock, DenseIndex j_startBlock, DenseIndex j_endBlock) const
Get a range [i,j) from the matrix. Indices are in block units.
Definition: SymmetricBlockMatrix.h:175
std::array< DenseIndex, 4 > calcIndices(DenseIndex iBlock, DenseIndex jBlock, DenseIndex blockRows, DenseIndex blockCols) const
Compute the indices into the underlying matrix for a given block.
Definition: SymmetricBlockMatrix.h:359
void negate()
Negate the entire active matrix.
Definition: SymmetricBlockMatrix.h:268
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J'th diagonal block as a self adjoint view.
Definition: SymmetricBlockMatrix.h:140
Eigen::SelfAdjointView< constBlock, Eigen::Upper > diagonalBlock(DenseIndex J) const
Return the J'th diagonal block as a self adjoint view.
Definition: SymmetricBlockMatrix.h:145
DenseIndex nOffsets() const
Number of offsets in the full matrix.
Definition: SymmetricBlockMatrix.h:315
void setZero()
Set the entire active matrix zero.
Definition: SymmetricBlockMatrix.h:263
Block block_(DenseIndex iBlock, DenseIndex jBlock, DenseIndex blockRows=1, DenseIndex blockCols=1)
Get an arbitrary block from the matrix. Indices are in block units.
Definition: SymmetricBlockMatrix.h:341
Matrix matrix_
The full matrix.
Definition: SymmetricBlockMatrix.h:59
DenseIndex blockStart() const
Retrieve the first logical block, i.e.
Definition: SymmetricBlockMatrix.h:291
constBlock full() const
Get the full matrix as a block.
Definition: SymmetricBlockMatrix.h:349
Vector diagonal(DenseIndex J) const
Get the diagonal of the J'th diagonal block.
Definition: SymmetricBlockMatrix.h:150
DenseIndex nActualBlocks() const
Number of actual blocks in the full matrix.
Definition: SymmetricBlockMatrix.h:320
Definition: SymmetricBlockMatrix.h:51
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
DenseIndex & blockStart()
Retrieve or modify the first logical block, i.e.
Definition: SymmetricBlockMatrix.h:287
Block aboveDiagonalRange(DenseIndex i_startBlock, DenseIndex i_endBlock, DenseIndex j_startBlock, DenseIndex j_endBlock)
Get a range [i,j) from the matrix. Indices are in block units.
Definition: SymmetricBlockMatrix.h:186
DenseIndex blockStart_
Changes apparent matrix view, see main class comment.
Definition: SymmetricBlockMatrix.h:62
typedef and functions to augment Eigen's MatrixXd
void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Update an off diagonal block.
Definition: SymmetricBlockMatrix.h:233
const MATRIX::ConstRowXpr row(const MATRIX &A, size_t j)
Extracts a row view from a matrix that avoids a copy.
Definition: Matrix.h:224
void setFullMatrix(const XprType &xpr)
Set the entire active matrix. Only reads the upper triangular part of xpr.
Definition: SymmetricBlockMatrix.h:258
DenseIndex nBlocks() const
Block count.
Definition: SymmetricBlockMatrix.h:125
void invertInPlace()
Invert the entire active matrix in place.
Definition: SymmetricBlockMatrix.h:273
Eigen::SelfAdjointView< Block, Eigen::Upper > selfadjointView()
Get self adjoint view.
Definition: SymmetricBlockMatrix.h:247
void updateDiagonalBlock(DenseIndex I, const XprType &xpr)
Increment the diagonal block by the values in xpr. Only reads the upper triangular part of xpr.
Definition: SymmetricBlockMatrix.h:217
SymmetricBlockMatrix(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool appendOneDimension=false)
Construct from iterator over the sizes of each vertical block.
Definition: SymmetricBlockMatrix.h:85
bool choleskyPartial(Matrix &ABC, size_t nFrontal, size_t topleft)
Partial Cholesky computes a factor [R S such that [R' 0 [R S = [A B 0 L] S' I] 0 L] B' C].
Definition: cholesky.cpp:108
Typedefs for easier changing of types.
SymmetricBlockMatrix(const CONTAINER &dimensions, const Matrix &matrix, bool appendOneDimension=false)
Construct from a container of the sizes of each vertical block and a pre-prepared matrix.
Definition: SymmetricBlockMatrix.h:95