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 
18 #pragma once
19 
20 #include <gtsam/base/FastVector.h>
21 #include <gtsam/base/Matrix.h>
22 #include <gtsam/base/types.h>
23 #include <gtsam/dllexport.h>
24 #if GTSAM_ENABLE_BOOST_SERIALIZATION
25 #include <boost/serialization/nvp.hpp>
26 #endif
27 #include <cassert>
28 #include <stdexcept>
29 #include <array>
30 
31 namespace boost {
32 namespace serialization {
33 class access;
34 } /* namespace serialization */
35 } /* namespace boost */
36 
37 namespace gtsam {
38 
39  // Forward declarations
40  class VerticalBlockMatrix;
41 
53  class GTSAM_EXPORT SymmetricBlockMatrix
54  {
55  public:
59 
60  protected:
63 
65 
66  public:
69 
71  template<typename CONTAINER>
72  SymmetricBlockMatrix(const CONTAINER& dimensions, bool appendOneDimension = false) :
73  blockStart_(0)
74  {
75  fillOffsets(dimensions.begin(), dimensions.end(), appendOneDimension);
76  matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
77  assertInvariants();
78  }
79 
81  template<typename ITERATOR>
82  SymmetricBlockMatrix(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool appendOneDimension = false) :
83  blockStart_(0)
84  {
85  fillOffsets(firstBlockDim, lastBlockDim, appendOneDimension);
86  matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
87  assertInvariants();
88  }
89 
91  template<typename CONTAINER>
92  SymmetricBlockMatrix(const CONTAINER& dimensions, const Matrix& matrix, bool appendOneDimension = false) :
93  blockStart_(0)
94  {
95  matrix_.resize(matrix.rows(), matrix.cols());
96  matrix_.triangularView<Eigen::Upper>() = matrix.triangularView<Eigen::Upper>();
97  fillOffsets(dimensions.begin(), dimensions.end(), appendOneDimension);
98  if(matrix_.rows() != matrix_.cols())
99  throw std::invalid_argument("Requested to create a SymmetricBlockMatrix from a non-square matrix.");
100  if(variableColOffsets_.back() != matrix_.cols())
101  throw std::invalid_argument("Requested to create a SymmetricBlockMatrix with dimensions that do not sum to the total size of the provided matrix.");
102  assertInvariants();
103  }
104 
108  static SymmetricBlockMatrix LikeActiveViewOf(const SymmetricBlockMatrix& other);
109 
113  static SymmetricBlockMatrix LikeActiveViewOf(const VerticalBlockMatrix& other);
114 
116  DenseIndex rows() const { assertInvariants(); return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
117 
119  DenseIndex cols() const { return rows(); }
120 
122  DenseIndex nBlocks() const { return nActualBlocks() - blockStart_; }
123 
126  return calcIndices(block, block, 1, 1)[2];
127  }
128 
131 
135 
138  return block_(J, J).selfadjointView<Eigen::Upper>();
139  }
140 
143  return block_(J, J).selfadjointView<Eigen::Upper>();
144  }
145 
148  return block_(J, J).diagonal();
149  }
150 
153  assert(I < J);
154  return block_(I, J);
155  }
156 
159  DenseIndex I, DenseIndex J) const {
160  assert(J > I);
161  return block_(I, I, J - I, J - I).selfadjointView<Eigen::Upper>();
162  }
163 
166  DenseIndex J) const {
167  assert(J > I);
168  return block_(I, I, J - I, J - I).triangularView<Eigen::Upper>();
169  }
170 
173  DenseIndex i_endBlock,
174  DenseIndex j_startBlock,
175  DenseIndex j_endBlock) const {
176  assert(i_startBlock < j_startBlock);
177  assert(i_endBlock <= j_startBlock);
178  return block_(i_startBlock, j_startBlock, i_endBlock - i_startBlock,
179  j_endBlock - j_startBlock);
180  }
181 
183  Block aboveDiagonalRange(DenseIndex i_startBlock, DenseIndex i_endBlock,
184  DenseIndex j_startBlock, DenseIndex j_endBlock) {
185  assert(i_startBlock < j_startBlock);
186  assert(i_endBlock <= j_startBlock);
187  return block_(i_startBlock, j_startBlock, i_endBlock - i_startBlock,
188  j_endBlock - j_startBlock);
189  }
190 
194 
196  template <typename XprType>
197  void setDiagonalBlock(DenseIndex I, const XprType& xpr) {
198  block_(I, I).triangularView<Eigen::Upper>() = xpr.template triangularView<Eigen::Upper>();
199  }
200 
202  template <typename XprType>
204  assert(I != J);
205  if (I < J) {
206  block_(I, J) = xpr;
207  } else {
208  block_(J, I) = xpr.transpose();
209  }
210  }
211 
213  template <typename XprType>
215  // TODO(gareth): Eigen won't let us add triangular or self-adjoint views
216  // here, so we do it manually.
217  auto dest = block_(I, I);
218  assert(dest.rows() == xpr.rows());
219  assert(dest.cols() == xpr.cols());
220  for (DenseIndex col = 0; col < dest.cols(); ++col) {
221  for (DenseIndex row = 0; row <= col; ++row) {
222  dest(row, col) += xpr(row, col);
223  }
224  }
225  }
226 
229  template <typename XprType>
231  assert(I != J);
232  if (I < J) {
233  block_(I, J).noalias() += xpr;
234  } else {
235  block_(J, I).noalias() += xpr.transpose();
236  }
237  }
238 
242 
245  return full().selfadjointView<Eigen::Upper>();
246  }
247 
250  return full().selfadjointView<Eigen::Upper>();
251  }
252 
254  template <typename XprType>
255  void setFullMatrix(const XprType& xpr) {
256  full().triangularView<Eigen::Upper>() = xpr.template triangularView<Eigen::Upper>();
257  }
258 
260  void setZero() {
261  full().triangularView<Eigen::Upper>().setZero();
262  }
263 
265  void setAllZero() {
266  matrix_.setZero();
267  }
268 
270  void negate();
271 
273  void invertInPlace();
274 
276 
280  DenseIndex& blockStart() { return blockStart_; }
281 
284  DenseIndex blockStart() const { return blockStart_; }
285 
296  void choleskyPartial(DenseIndex nFrontals);
297 
304 
305  protected:
306 
309  return variableColOffsets_.size();
310  }
311 
314  return nOffsets() - 1;
315  }
316 
319  assert(block >= 0);
320  const DenseIndex actual_index = block + blockStart();
321  assert(actual_index < nOffsets());
322  return variableColOffsets_[actual_index];
323  }
324 
327  DenseIndex blockRows = 1, DenseIndex blockCols = 1) const {
328  const std::array<DenseIndex, 4> indices =
329  calcIndices(iBlock, jBlock, blockRows, blockCols);
330  return matrix_.block(indices[0], indices[1], indices[2], indices[3]);
331  }
332 
334  Block block_(DenseIndex iBlock, DenseIndex jBlock, DenseIndex blockRows = 1,
335  DenseIndex blockCols = 1) {
336  const std::array<DenseIndex, 4> indices =
337  calcIndices(iBlock, jBlock, blockRows, blockCols);
338  return matrix_.block(indices[0], indices[1], indices[2], indices[3]);
339  }
340 
342  constBlock full() const {
343  return block_(0, 0, nBlocks(), nBlocks());
344  }
345 
348  return block_(0, 0, nBlocks(), nBlocks());
349  }
350 
352  std::array<DenseIndex, 4> calcIndices(DenseIndex iBlock, DenseIndex jBlock,
353  DenseIndex blockRows,
354  DenseIndex blockCols) const {
355  assert(blockRows >= 0);
356  assert(blockCols >= 0);
357 
358  // adjust indices to account for start and size of blocks
359  const DenseIndex denseI = offset(iBlock);
360  const DenseIndex denseJ = offset(jBlock);
361  const DenseIndex denseRows = offset(iBlock + blockRows) - denseI;
362  const DenseIndex denseCols = offset(jBlock + blockCols) - denseJ;
363  return {{denseI, denseJ, denseRows, denseCols}};
364  }
365 
366  void assertInvariants() const
367  {
368  assert(matrix_.rows() == matrix_.cols());
369  assert(matrix_.cols() == variableColOffsets_.back());
370  assert(blockStart_ < (DenseIndex)variableColOffsets_.size());
371  }
372 
373  template<typename ITERATOR>
374  void fillOffsets(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool appendOneDimension)
375  {
376  variableColOffsets_.resize((lastBlockDim-firstBlockDim) + 1 + (appendOneDimension ? 1 : 0));
377  variableColOffsets_[0] = 0;
378  DenseIndex j=0;
379  for(ITERATOR dim=firstBlockDim; dim!=lastBlockDim; ++dim) {
380  variableColOffsets_[j+1] = variableColOffsets_[j] + *dim;
381  ++ j;
382  }
383  if(appendOneDimension)
384  {
385  variableColOffsets_[j+1] = variableColOffsets_[j] + 1;
386  ++ j;
387  }
388  }
389 
390  friend class VerticalBlockMatrix;
391  template<typename SymmetricBlockMatrixType> friend class SymmetricBlockMatrixBlockExpr;
392 
393  private:
394 #if GTSAM_ENABLE_BOOST_SERIALIZATION
395 
396  friend class boost::serialization::access;
397  template<class ARCHIVE>
398  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
399  // Fill in the lower triangle part of the matrix, so boost::serialization won't
400  // complain about uninitialized data with an input_stream_error exception
401  // http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/exceptions.html#stream_error
402  matrix_.triangularView<Eigen::Lower>() = matrix_.triangularView<Eigen::Upper>().transpose();
403  ar & BOOST_SERIALIZATION_NVP(matrix_);
404  ar & BOOST_SERIALIZATION_NVP(variableColOffsets_);
405  ar & BOOST_SERIALIZATION_NVP(blockStart_);
406  }
407 #endif
408  };
409 
411  class CholeskyFailed;
412 
413 }
dimensions
const std::vector< size_t > dimensions
Definition: testVerticalBlockMatrix.cpp:27
gtsam::SymmetricBlockMatrix::Block
Eigen::Block< Matrix > Block
Definition: SymmetricBlockMatrix.h:57
col
m col(1)
gtsam::SymmetricBlockMatrix::block_
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:334
Eigen::Block
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
gtsam::SymmetricBlockMatrix::assertInvariants
void assertInvariants() const
Definition: SymmetricBlockMatrix.h:366
gtsam::SymmetricBlockMatrix::block_
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:326
gtsam::SymmetricBlockMatrix::setOffDiagonalBlock
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:203
FastVector.h
A thin wrapper around std::vector that uses a custom allocator.
Eigen::CwiseBinaryOp
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition: CwiseBinaryOp.h:77
gtsam::SymmetricBlockMatrix::full
constBlock full() const
Get the full matrix as a block.
Definition: SymmetricBlockMatrix.h:342
gtsam::SymmetricBlockMatrix::blockStart_
DenseIndex blockStart_
Changes apparent matrix view, see main class comment.
Definition: SymmetricBlockMatrix.h:64
types.h
Typedefs for easier changing of types.
gtsam::SymmetricBlockMatrix::nActualBlocks
DenseIndex nActualBlocks() const
Number of actual blocks in the full matrix.
Definition: SymmetricBlockMatrix.h:313
gtsam::FastVector
std::vector< T, typename internal::FastDefaultVectorAllocator< T >::type > FastVector
Definition: FastVector.h:34
Matrix.h
typedef and functions to augment Eigen's MatrixXd
Eigen::Upper
@ Upper
Definition: Constants.h:211
gtsam::SymmetricBlockMatrix::selfadjointView
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:158
gtsam::SymmetricBlockMatrix::full
Block full()
Get the full matrix as a block.
Definition: SymmetricBlockMatrix.h:347
gtsam::SymmetricBlockMatrix::blockStart
DenseIndex blockStart() const
Definition: SymmetricBlockMatrix.h:284
gtsam::Matrix
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:39
Eigen::SelfAdjointView
Expression of a selfadjoint matrix from a triangular part of a dense matrix.
Definition: SelfAdjointView.h:49
gtsam::SymmetricBlockMatrix::setDiagonalBlock
void setDiagonalBlock(DenseIndex I, const XprType &xpr)
Set a diagonal block. Only the upper triangular portion of xpr is evaluated.
Definition: SymmetricBlockMatrix.h:197
boost
Definition: boostmultiprec.cpp:109
gtsam::SymmetricBlockMatrix::diagonalBlock
Eigen::SelfAdjointView< constBlock, Eigen::Upper > diagonalBlock(DenseIndex J) const
Return the J'th diagonal block as a self adjoint view.
Definition: SymmetricBlockMatrix.h:142
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:39
gtsam::SymmetricBlockMatrix::aboveDiagonalRange
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:172
rows
int rows
Definition: Tutorial_commainit_02.cpp:1
block
m m block(1, 0, 2, 2)<< 4
test_eigen_tensor.indices
indices
Definition: test_eigen_tensor.py:33
gtsam::SymmetricBlockMatrix::SymmetricBlockMatrix
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:92
gtsam::SymmetricBlockMatrix::aboveDiagonalRange
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:183
gtsam::SymmetricBlockMatrix::matrix_
Matrix matrix_
The full matrix.
Definition: SymmetricBlockMatrix.h:61
J
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
gtsam::VerticalBlockMatrix
Definition: VerticalBlockMatrix.h:44
Eigen::internal::negate
T negate(const T &x)
Definition: packetmath_test_shared.h:24
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
I
#define I
Definition: main.h:112
gtsam::row
const MATRIX::ConstRowXpr row(const MATRIX &A, size_t j)
Definition: base/Matrix.h:215
gtsam::SymmetricBlockMatrix::setAllZero
void setAllZero()
Set entire matrix zero.
Definition: SymmetricBlockMatrix.h:265
gtsam::SymmetricBlockMatrix::setFullMatrix
void setFullMatrix(const XprType &xpr)
Set the entire active matrix. Only reads the upper triangular part of xpr.
Definition: SymmetricBlockMatrix.h:255
gtsam::SymmetricBlockMatrix::SymmetricBlockMatrix
SymmetricBlockMatrix(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool appendOneDimension=false)
Construct from iterator over the sizes of each vertical block.
Definition: SymmetricBlockMatrix.h:82
gtsam::SymmetricBlockMatrix::nBlocks
DenseIndex nBlocks() const
Block count.
Definition: SymmetricBlockMatrix.h:122
Eigen::Lower
@ Lower
Definition: Constants.h:209
gtsam::SymmetricBlockMatrix::rows
DenseIndex rows() const
Row size.
Definition: SymmetricBlockMatrix.h:116
matrix
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: gtsam/3rdparty/Eigen/blas/common.h:110
offset
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate offset
Definition: gnuplot_common_settings.hh:64
gtsam::SymmetricBlockMatrix::This
SymmetricBlockMatrix This
Definition: SymmetricBlockMatrix.h:56
gtsam::SymmetricBlockMatrix::nOffsets
DenseIndex nOffsets() const
Number of offsets in the full matrix.
Definition: SymmetricBlockMatrix.h:308
gtsam::SymmetricBlockMatrix::triangularView
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:165
gtsam::SymmetricBlockMatrix::calcIndices
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:352
gtsam::SymmetricBlockMatrix::updateDiagonalBlock
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:214
gtsam::SymmetricBlockMatrix::selfadjointView
Eigen::SelfAdjointView< Block, Eigen::Upper > selfadjointView()
Get self adjoint view.
Definition: SymmetricBlockMatrix.h:244
gtsam::SymmetricBlockMatrix::cols
DenseIndex cols() const
Column size.
Definition: SymmetricBlockMatrix.h:119
Eigen::CwiseBinaryOp::cols
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: CwiseBinaryOp.h:125
gtsam
traits
Definition: SFMdata.h:40
gtsam::SymmetricBlockMatrix::setZero
void setZero()
Set the entire active matrix zero.
Definition: SymmetricBlockMatrix.h:260
gtsam::choleskyPartial
bool choleskyPartial(Matrix &ABC, size_t nFrontal, size_t topleft)
Definition: base/cholesky.cpp:108
gtsam::DenseIndex
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:103
gtsam::SymmetricBlockMatrix::updateOffDiagonalBlock
void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Definition: SymmetricBlockMatrix.h:230
gtsam::SymmetricBlockMatrix::diagonal
Vector diagonal(DenseIndex J) const
Get the diagonal of the J'th diagonal block.
Definition: SymmetricBlockMatrix.h:147
gtsam::SymmetricBlockMatrix::diagonalBlock
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J'th diagonal block as a self adjoint view.
Definition: SymmetricBlockMatrix.h:137
gtsam::split
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
Definition: graph-inl.h:245
gtsam::SymmetricBlockMatrix::getDim
DenseIndex getDim(DenseIndex block) const
Number of dimensions for variable on this diagonal block.
Definition: SymmetricBlockMatrix.h:125
setZero
v setZero(3)
gtsam::SymmetricBlockMatrix::blockStart
DenseIndex & blockStart()
Definition: SymmetricBlockMatrix.h:280
gtsam::SymmetricBlockMatrix::offset
DenseIndex offset(DenseIndex block) const
Get an offset for a block index (in the active view).
Definition: SymmetricBlockMatrix.h:318
gtsam::SymmetricBlockMatrix::SymmetricBlockMatrix
SymmetricBlockMatrix(const CONTAINER &dimensions, bool appendOneDimension=false)
Construct from a container of the sizes of each block.
Definition: SymmetricBlockMatrix.h:72
gtsam::SymmetricBlockMatrix::aboveDiagonalBlock
constBlock aboveDiagonalBlock(DenseIndex I, DenseIndex J) const
Get block above the diagonal (I, J).
Definition: SymmetricBlockMatrix.h:152
gtsam::SymmetricBlockMatrix::constBlock
Eigen::Block< const Matrix > constBlock
Definition: SymmetricBlockMatrix.h:58
gtsam::SymmetricBlockMatrix::selfadjointView
Eigen::SelfAdjointView< constBlock, Eigen::Upper > selfadjointView() const
Get self adjoint view.
Definition: SymmetricBlockMatrix.h:249
Eigen::TriangularView
Expression of a triangular part in a matrix.
Definition: TriangularMatrix.h:187
gtsam::SymmetricBlockMatrix
Definition: SymmetricBlockMatrix.h:53
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
gtsam::SymmetricBlockMatrix::fillOffsets
void fillOffsets(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool appendOneDimension)
Definition: SymmetricBlockMatrix.h:374
gtsam::SymmetricBlockMatrix::variableColOffsets_
FastVector< DenseIndex > variableColOffsets_
the starting columns of each block (0-based)
Definition: SymmetricBlockMatrix.h:62
Eigen::CwiseBinaryOp::rows
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: CwiseBinaryOp.h:120


gtsam
Author(s):
autogenerated on Wed Mar 19 2025 03:04:38