gtsam
Loading...
Searching...
No Matches
SymmetricBlockMatrix.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3* GTSAM Copyright 2010, Georgia Tech Research Corporation,
4* Atlanta, Georgia 30332-0415
5* All Rights Reserved
6* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8* See LICENSE for the license information
9
10* -------------------------------------------------------------------------- */
11
19#pragma once
20
22#include <gtsam/base/Matrix.h>
23#include <gtsam/base/types.h>
24#include <gtsam/dllexport.h>
25#if GTSAM_ENABLE_BOOST_SERIALIZATION
26#include <boost/serialization/nvp.hpp>
27#endif
28#include <algorithm>
29#include <array>
30#include <cassert>
31#include <cstring>
32#include <stdexcept>
33#include <vector>
34
35namespace boost {
36namespace serialization {
37class access;
38} /* namespace serialization */
39} /* namespace boost */
40
41namespace gtsam {
42
43namespace internal {
44
45class CompactLeafSchurKernel;
46
49 DenseIndex begin;
50 DenseIndex end;
51
53 bool operator()(DenseIndex column) const {
54 return column >= begin && column < end;
55 }
56
58 bool owns(DenseIndex I, DenseIndex J) const {
59 return (*this)(std::max(I, J));
60 }
61};
62} // namespace internal
63
64// Forward declarations
65class VerticalBlockMatrix;
66
80class GTSAM_EXPORT SymmetricBlockMatrix {
81 public:
82 typedef SymmetricBlockMatrix This;
83 typedef Eigen::Block<Matrix> Block;
84 typedef Eigen::Block<const Matrix> constBlock;
85
86 protected:
87 Matrix matrix_;
90
93
94 public:
97
99 template <typename CONTAINER>
100 SymmetricBlockMatrix(const CONTAINER& dimensions,
101 bool appendOneDimension = false)
102 : blockStart_(0) {
103 fillOffsets(dimensions.begin(), dimensions.end(), appendOneDimension);
104 matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
105 assertInvariants();
106 }
107
109 template <typename ITERATOR>
110 SymmetricBlockMatrix(ITERATOR firstBlockDim, ITERATOR lastBlockDim,
111 bool appendOneDimension = false)
112 : blockStart_(0) {
113 fillOffsets(firstBlockDim, lastBlockDim, appendOneDimension);
114 matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
115 assertInvariants();
116 }
117
120 template <typename CONTAINER>
121 SymmetricBlockMatrix(const CONTAINER& dimensions, const Matrix& matrix,
122 bool appendOneDimension = false)
123 : blockStart_(0) {
124 matrix_.resize(matrix.rows(), matrix.cols());
125 matrix_.triangularView<Eigen::Upper>() =
126 matrix.triangularView<Eigen::Upper>();
127 fillOffsets(dimensions.begin(), dimensions.end(), appendOneDimension);
128 if (matrix_.rows() != matrix_.cols())
129 throw std::invalid_argument(
130 "Requested to create a SymmetricBlockMatrix from a non-square "
131 "matrix.");
132 if (variableColOffsets_.back() != matrix_.cols())
133 throw std::invalid_argument(
134 "Requested to create a SymmetricBlockMatrix with dimensions that do "
135 "not sum to the total size of the provided matrix.");
136 assertInvariants();
137 }
138
143 static SymmetricBlockMatrix LikeActiveViewOf(
144 const SymmetricBlockMatrix& other);
145
149 static SymmetricBlockMatrix LikeActiveViewOf(
150 const VerticalBlockMatrix& other);
151
153 DenseIndex rows() const {
154 assertInvariants();
156 }
157
159 DenseIndex cols() const { return rows(); }
160
163
166 return calcIndices(block, block, 1, 1)[2];
167 }
168
171
174
178 Matrix block(DenseIndex I, DenseIndex J) const;
179
186 constBlock blockView(DenseIndex I, DenseIndex J) const {
187 return block_(I, J);
188 }
189
191 Eigen::SelfAdjointView<Block, Eigen::Upper> diagonalBlock(DenseIndex J) {
192 return block_(J, J).selfadjointView<Eigen::Upper>();
193 }
194
196 Eigen::SelfAdjointView<constBlock, Eigen::Upper> diagonalBlock(
197 DenseIndex J) const {
198 return block_(J, J).selfadjointView<Eigen::Upper>();
199 }
200
202 Vector diagonal(DenseIndex J) const { return block_(J, J).diagonal(); }
203
205 constBlock aboveDiagonalBlock(DenseIndex I, DenseIndex J) const {
206 assert(I < J);
207 return block_(I, J);
208 }
209
211 Eigen::SelfAdjointView<constBlock, Eigen::Upper> selfadjointView(
212 DenseIndex I, DenseIndex J) const {
213 assert(J > I);
214 return block_(I, I, J - I, J - I).selfadjointView<Eigen::Upper>();
215 }
216
219 Eigen::TriangularView<constBlock, Eigen::Upper> triangularView(
220 DenseIndex I, DenseIndex J) const {
221 assert(J > I);
222 return block_(I, I, J - I, J - I).triangularView<Eigen::Upper>();
223 }
224
226 constBlock aboveDiagonalRange(DenseIndex i_startBlock, DenseIndex i_endBlock,
227 DenseIndex j_startBlock,
228 DenseIndex j_endBlock) const {
229 assert(i_startBlock < j_startBlock);
230 assert(i_endBlock <= j_startBlock);
231 return block_(i_startBlock, j_startBlock, i_endBlock - i_startBlock,
232 j_endBlock - j_startBlock);
233 }
234
236 Block aboveDiagonalRange(DenseIndex i_startBlock, DenseIndex i_endBlock,
237 DenseIndex j_startBlock, DenseIndex j_endBlock) {
238 assert(i_startBlock < j_startBlock);
239 assert(i_endBlock <= j_startBlock);
240 return block_(i_startBlock, j_startBlock, i_endBlock - i_startBlock,
241 j_endBlock - j_startBlock);
242 }
243
247
250 template <typename XprType>
251 void setDiagonalBlock(DenseIndex I, const XprType& xpr) {
252 block_(I, I).triangularView<Eigen::Upper>() =
253 xpr.template triangularView<Eigen::Upper>();
254 }
255
258 template <typename XprType>
259 void setOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType& xpr) {
260 assert(I != J);
261 if (I < J) {
262 block_(I, J) = xpr;
263 } else {
264 block_(J, I) = xpr.transpose();
265 }
266 }
267
270 template <typename XprType>
271 void updateDiagonalBlock(DenseIndex I, const XprType& xpr) {
272 // TODO(gareth): Eigen won't let us add triangular or self-adjoint views
273 // here, so we do it manually.
274 auto dest = block_(I, I);
275 assert(dest.rows() == xpr.rows());
276 assert(dest.cols() == xpr.cols());
277 for (DenseIndex col = 0; col < dest.cols(); ++col) {
278 for (DenseIndex row = 0; row <= col; ++row) {
279 dest(row, col) += xpr(row, col);
280 }
281 }
282 }
283
285 template <typename XprType>
286 void updateDiagonalBlockAt(DenseIndex scalarOffset, const XprType& xpr) {
287 auto dest =
288 matrix_.block(scalarOffset, scalarOffset, xpr.rows(), xpr.cols());
289 assert(dest.rows() == dest.cols());
290 for (DenseIndex col = 0; col < dest.cols(); ++col) {
291 for (DenseIndex row = 0; row <= col; ++row) {
292 dest(row, col) += xpr(row, col);
293 }
294 }
295 }
296
298 template <int Dimension, typename XprType>
299 void updateFixedDiagonalBlockAt(DenseIndex scalarOffset, const XprType& xpr) {
300 auto dest = matrix_.template block<Dimension, Dimension>(scalarOffset,
301 scalarOffset);
302 for (int col = 0; col < Dimension; ++col) {
303 for (int row = 0; row <= col; ++row) {
304 dest(row, col) += xpr(row, col);
305 }
306 }
307 }
308
310 void addToDiagonalBlock(DenseIndex I, const Vector& deltaDiag) {
311 auto dest = block_(I, I);
312 assert(dest.rows() == deltaDiag.size());
313 dest.diagonal().array() += deltaDiag.array();
314 }
315
317 void addScaledIdentity(DenseIndex I, double lambda) {
318 auto dest = block_(I, I);
319 dest.diagonal().array() += lambda;
320 }
321
324 template <typename XprType>
325 void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType& xpr) {
326 assert(I != J);
327 if constexpr (XprType::SizeAtCompileTime == 1) {
328 if (I < J) {
329 auto destination = block_(I, J);
330 assert(destination.rows() == 1 && destination.cols() == 1);
331 destination(0, 0) += xpr.coeff(0, 0);
332 } else {
333 auto destination = block_(J, I);
334 assert(destination.rows() == 1 && destination.cols() == 1);
335 destination(0, 0) += xpr.coeff(0, 0);
336 }
337 } else {
338 if (I < J) {
339 block_(I, J).noalias() += xpr;
340 } else {
341 block_(J, I).noalias() += xpr.transpose();
342 }
343 }
344 }
345
347 template <typename XprType>
349 const XprType& xpr) {
350 assert(rowOffset < colOffset);
351 if constexpr (XprType::SizeAtCompileTime == 1) {
352 matrix_(rowOffset, colOffset) += xpr.coeff(0, 0);
353 } else {
354 matrix_.block(rowOffset, colOffset, xpr.rows(), xpr.cols()) += xpr;
355 }
356 }
357
359 template <int Rows, int Cols, typename XprType>
361 const XprType& xpr) {
362 assert(rowOffset < colOffset);
363 if constexpr (Rows == 1 && Cols == 1) {
364 assert(xpr.rows() == 1 && xpr.cols() == 1);
365 matrix_(rowOffset, colOffset) += xpr.coeff(0, 0);
366 } else {
367 matrix_.template block<Rows, Cols>(rowOffset, colOffset) += xpr;
368 }
369 }
370
373 void updateFromMappedBlocks(const SymmetricBlockMatrix& other,
374 const std::vector<DenseIndex>& blockIndices);
375
377 void updateFromMappedBlocks(const SymmetricBlockMatrix& other,
378 const std::vector<DenseIndex>& blockIndices,
379 const std::vector<DenseIndex>& scalarOffsets);
380
388 void updateFromMappedBlocks(const SymmetricBlockMatrix& other,
389 DenseIndex sourceBlockStart,
390 const std::vector<DenseIndex>& blockIndices,
391 const std::vector<DenseIndex>& scalarOffsets);
392
401 void updateFromMappedBlockColumn(const SymmetricBlockMatrix& other,
402 DenseIndex sourceBlockStart,
403 DenseIndex ownedSourceBlock,
404 const std::vector<DenseIndex>& blockIndices,
405 const std::vector<DenseIndex>& scalarOffsets,
406 bool ownLastCrossBlock = false);
407
412 void updateFromOuterProductBlocks(const VerticalBlockMatrix& other,
413 const std::vector<DenseIndex>& blockIndices,
414 double alpha = 1.0);
415
420 void updateFromOuterProductBlocks(
421 const VerticalBlockMatrix& other, DenseIndex sourceRowBegin,
422 DenseIndex sourceRowEnd, DenseIndex sourceBlockStart,
423 const std::vector<DenseIndex>& blockIndices,
424 const std::vector<DenseIndex>& scalarOffsets, double alpha = 1.0);
425
428 assert(nBlocks() == other.nBlocks());
429 full().triangularView<Eigen::Upper>() += other.full();
430 }
431
435
437 Eigen::SelfAdjointView<Block, Eigen::Upper> selfadjointView() {
438 return full().selfadjointView<Eigen::Upper>();
439 }
440
442 Eigen::SelfAdjointView<constBlock, Eigen::Upper> selfadjointView() const {
443 return full().selfadjointView<Eigen::Upper>();
444 }
445
448 template <typename XprType>
449 void setFullMatrix(const XprType& xpr) {
450 full().triangularView<Eigen::Upper>() =
451 xpr.template triangularView<Eigen::Upper>();
452 }
453
455 void setZero() { full().triangularView<Eigen::Upper>().setZero(); }
456
458 void setAllZero() { matrix_.setZero(); }
459
462 void setZeroColumns(DenseIndex beginCol, DenseIndex endCol) {
463 assert(beginCol < endCol);
464 assert(beginCol >= 0);
465 assert(endCol >= 0);
466 assert(beginCol < nBlocks());
467 assert(endCol <= nBlocks());
468 static_assert(Matrix::IsRowMajor == 0,
469 "setZeroColumns requires column-major storage.");
470
471 const DenseIndex denseBeginCol = offset(beginCol);
472 const DenseIndex denseEndCol = offset(endCol);
473
474 double* begin = matrix_.data() + denseBeginCol * matrix_.rows();
475 double* end = matrix_.data() + denseEndCol * matrix_.rows();
476
477 // Using memset for maximal compiler optimization.
478 memset(begin, 0, (end - begin) * sizeof(*begin));
479 }
480
482 void negate();
483
485 void invertInPlace();
486
488
493
498
508 void choleskyPartial(DenseIndex nFrontals);
509
517
519 void split(DenseIndex nFrontals, VerticalBlockMatrix* RSd);
520
521 protected:
523 DenseIndex nOffsets() const { return variableColOffsets_.size(); }
524
526 DenseIndex nActualBlocks() const { return nOffsets() - 1; }
527
530 assert(block >= 0);
531 const DenseIndex actual_index = block + blockStart();
532 assert(actual_index < nOffsets());
533 return variableColOffsets_[actual_index];
534 }
535
537 constBlock block_(DenseIndex iBlock, DenseIndex jBlock,
538 DenseIndex blockRows = 1, DenseIndex blockCols = 1) const {
539 const std::array<DenseIndex, 4> indices =
540 calcIndices(iBlock, jBlock, blockRows, blockCols);
541 return matrix_.block(indices[0], indices[1], indices[2], indices[3]);
542 }
543
545 Block block_(DenseIndex iBlock, DenseIndex jBlock, DenseIndex blockRows = 1,
546 DenseIndex blockCols = 1) {
547 const std::array<DenseIndex, 4> indices =
548 calcIndices(iBlock, jBlock, blockRows, blockCols);
549 return matrix_.block(indices[0], indices[1], indices[2], indices[3]);
550 }
551
553 constBlock full() const { return block_(0, 0, nBlocks(), nBlocks()); }
554
556 Block full() { return block_(0, 0, nBlocks(), nBlocks()); }
557
559 std::array<DenseIndex, 4> calcIndices(DenseIndex iBlock, DenseIndex jBlock,
560 DenseIndex blockRows,
561 DenseIndex blockCols) const {
562 assert(blockRows >= 0);
563 assert(blockCols >= 0);
564
565 // adjust indices to account for start and size of blocks
566 const DenseIndex denseI = offset(iBlock);
567 const DenseIndex denseJ = offset(jBlock);
568 const DenseIndex denseRows = offset(iBlock + blockRows) - denseI;
569 const DenseIndex denseCols = offset(jBlock + blockCols) - denseJ;
570 return {{denseI, denseJ, denseRows, denseCols}};
571 }
572
573 void assertInvariants() const {
574 assert(matrix_.rows() == matrix_.cols());
575 assert(matrix_.cols() == variableColOffsets_.back());
576 assert(blockStart_ < (DenseIndex)variableColOffsets_.size());
577 }
578
579 template <typename ITERATOR>
580 void fillOffsets(ITERATOR firstBlockDim, ITERATOR lastBlockDim,
581 bool appendOneDimension) {
582 variableColOffsets_.resize((lastBlockDim - firstBlockDim) + 1 +
583 (appendOneDimension ? 1 : 0));
584 variableColOffsets_[0] = 0;
585 DenseIndex j = 0;
586 for (ITERATOR dim = firstBlockDim; dim != lastBlockDim; ++dim) {
587 variableColOffsets_[j + 1] = variableColOffsets_[j] + *dim;
588 ++j;
589 }
590 if (appendOneDimension) {
591 variableColOffsets_[j + 1] = variableColOffsets_[j] + 1;
592 ++j;
593 }
594 }
595
596 friend class VerticalBlockMatrix;
597 friend class internal::CompactLeafSchurKernel;
598 template <typename SymmetricBlockMatrixType>
599 friend class SymmetricBlockMatrixBlockExpr;
600
601 private:
602#if GTSAM_ENABLE_BOOST_SERIALIZATION
604 friend class boost::serialization::access;
605 template <class ARCHIVE>
606 void serialize(ARCHIVE& ar, const unsigned int /*version*/) {
607 // Fill in the lower triangle part of the matrix, so boost::serialization
608 // won't complain about uninitialized data with an input_stream_error
609 // exception
610 // http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/exceptions.html#stream_error
611 matrix_.triangularView<Eigen::Lower>() =
612 matrix_.triangularView<Eigen::Upper>().transpose();
613 ar& BOOST_SERIALIZATION_NVP(matrix_);
614 ar& BOOST_SERIALIZATION_NVP(variableColOffsets_);
615 ar& BOOST_SERIALIZATION_NVP(blockStart_);
616 }
617#endif
618};
619
621class CholeskyFailed;
622
623} // namespace gtsam
A thin wrapper around std::vector that uses a custom allocator.
Typedefs for easier changing of types.
typedef and functions to augment Eigen's MatrixXd
std::vector< T, typename internal::FastDefaultVectorAllocator< T >::type > FastVector
FastVector is a type alias to a std::vector with a custom memory allocator.
Definition FastVector.h:33
Global functions in a separate testing namespace.
Definition chartTesting.h:28
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition types.h:49
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:245
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:114
Half-open range of physical upper-triangular block columns.
Definition SymmetricBlockMatrix.h:48
bool operator()(DenseIndex column) const
Return whether this range owns a physical block column.
Definition SymmetricBlockMatrix.h:53
bool owns(DenseIndex I, DenseIndex J) const
Return whether this range owns the stored block for logical indices I,J.
Definition SymmetricBlockMatrix.h:58
This class stores a dense matrix and allows it to be accessed as a collection of blocks.
Definition SymmetricBlockMatrix.h:80
Block full()
Get the full matrix as a block.
Definition SymmetricBlockMatrix.h:556
DenseIndex blockStart_
Changes apparent matrix view, see main class comment.
Definition SymmetricBlockMatrix.h:92
void updateFixedOffDiagonalBlockAt(DenseIndex rowOffset, DenseIndex colOffset, const XprType &xpr)
Increment a fixed-size upper block using cached scalar offsets.
Definition SymmetricBlockMatrix.h:360
void setZeroColumns(DenseIndex beginCol, DenseIndex endCol)
Set the block columns between beginCol (inclusive) and endCol (exclusive) to zero.
Definition SymmetricBlockMatrix.h:462
void setDiagonalBlock(DenseIndex I, const XprType &xpr)
Set a diagonal block.
Definition SymmetricBlockMatrix.h:251
DenseIndex nActualBlocks() const
Number of actual blocks in the full matrix.
Definition SymmetricBlockMatrix.h:526
Vector diagonal(DenseIndex J) const
Get the diagonal of the J'th diagonal block.
Definition SymmetricBlockMatrix.h:202
Matrix matrix_
The full matrix.
Definition SymmetricBlockMatrix.h:87
void setAllZero()
Set entire matrix zero.
Definition SymmetricBlockMatrix.h:458
void addToDiagonalBlock(DenseIndex I, const Vector &deltaDiag)
Add a vector to the diagonal entries of block I.
Definition SymmetricBlockMatrix.h:310
DenseIndex cols() const
Column size.
Definition SymmetricBlockMatrix.h:159
DenseIndex getDim(DenseIndex block) const
Number of dimensions for variable on this diagonal block.
Definition SymmetricBlockMatrix.h:165
void setZero()
Set the entire active matrix zero.
Definition SymmetricBlockMatrix.h:455
void setOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Set an off-diagonal block.
Definition SymmetricBlockMatrix.h:259
void setFullMatrix(const XprType &xpr)
Set the entire active matrix.
Definition SymmetricBlockMatrix.h:449
Eigen::SelfAdjointView< Block, Eigen::Upper > selfadjointView()
Get self adjoint view.
Definition SymmetricBlockMatrix.h:437
constBlock aboveDiagonalBlock(DenseIndex I, DenseIndex J) const
Get block above the diagonal (I, J).
Definition SymmetricBlockMatrix.h:205
void addUpperTriangular(const SymmetricBlockMatrix &other)
Add the upper-triangular part of another symmetric block matrix.
Definition SymmetricBlockMatrix.h:427
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:537
void updateFixedDiagonalBlockAt(DenseIndex scalarOffset, const XprType &xpr)
Increment a fixed-size diagonal block using its cached scalar offset.
Definition SymmetricBlockMatrix.h:299
constBlock full() const
Get the full matrix as a block.
Definition SymmetricBlockMatrix.h:553
DenseIndex rows() const
Row size.
Definition SymmetricBlockMatrix.h:153
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:236
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:219
Eigen::SelfAdjointView< constBlock, Eigen::Upper > diagonalBlock(DenseIndex J) const
Return the J'th diagonal block as a self adjoint view.
Definition SymmetricBlockMatrix.h:196
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:121
DenseIndex blockStart() const
Retrieve the first logical block, i.e.
Definition SymmetricBlockMatrix.h:497
Matrix block(DenseIndex I, DenseIndex J) const
Get a copy of a block (anywhere in the matrix).
Definition SymmetricBlockMatrix.cpp:65
Eigen::SelfAdjointView< constBlock, Eigen::Upper > selfadjointView() const
Get self adjoint view.
Definition SymmetricBlockMatrix.h:442
void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Update an off diagonal block.
Definition SymmetricBlockMatrix.h:325
SymmetricBlockMatrix(const CONTAINER &dimensions, bool appendOneDimension=false)
Construct from a container of the sizes of each block.
Definition SymmetricBlockMatrix.h:100
void updateDiagonalBlockAt(DenseIndex scalarOffset, const XprType &xpr)
Increment a diagonal block using its cached scalar offset.
Definition SymmetricBlockMatrix.h:286
DenseIndex blockScalarOffset(DenseIndex block) const
Return the scalar offset of a block in the underlying matrix.
Definition SymmetricBlockMatrix.h:170
SymmetricBlockMatrix(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool appendOneDimension=false)
Construct from iterator over the sizes of each vertical block.
Definition SymmetricBlockMatrix.h:110
DenseIndex & blockStart()
Retrieve or modify the first logical block, i.e.
Definition SymmetricBlockMatrix.h:492
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:226
SymmetricBlockMatrix()
Construct from an empty matrix (asserts that the matrix is empty).
Definition SymmetricBlockMatrix.cpp:31
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J'th diagonal block as a self adjoint view.
Definition SymmetricBlockMatrix.h:191
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:545
void updateDiagonalBlock(DenseIndex I, const XprType &xpr)
Increment the diagonal block by the values in xpr.
Definition SymmetricBlockMatrix.h:271
DenseIndex nOffsets() const
Number of offsets in the full matrix.
Definition SymmetricBlockMatrix.h:523
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:559
DenseIndex nBlocks() const
Block count.
Definition SymmetricBlockMatrix.h:162
FastVector< DenseIndex > variableColOffsets_
the starting columns of each block (0-based)
Definition SymmetricBlockMatrix.h:89
constBlock blockView(DenseIndex I, DenseIndex J) const
Get a block view (anywhere in the matrix) without allocating a copy.
Definition SymmetricBlockMatrix.h:186
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:211
void addScaledIdentity(DenseIndex I, double lambda)
Add lambda * I to the diagonal block I.
Definition SymmetricBlockMatrix.h:317
DenseIndex offset(DenseIndex block) const
Get an offset for a block index (in the active view).
Definition SymmetricBlockMatrix.h:529
void updateOffDiagonalBlockAt(DenseIndex rowOffset, DenseIndex colOffset, const XprType &xpr)
Increment an upper off-diagonal block using cached scalar offsets.
Definition SymmetricBlockMatrix.h:348
Indicate Cholesky factorization failure.
Definition ThreadsafeException.h:116
This class stores a dense matrix and allows it to be accessed as a collection of vertical blocks.
Definition VerticalBlockMatrix.h:47