Format using BORG conventions

release/4.3a0
dellaert 2014-02-15 11:47:25 -05:00
parent 9af77a9d93
commit 6a8084ee02
1 changed files with 349 additions and 293 deletions

View File

@ -27,34 +27,38 @@ namespace gtsam {
class VerticalBlockMatrix;
/**
* This class stores a dense matrix and allows it to be accessed as a collection of blocks. When
* constructed, the caller must provide the dimensions of the blocks.
* This class stores a dense matrix and allows it to be accessed as a
* collection of blocks. When constructed, the caller must provide the
* dimensions of the blocks.
*
* The block structure is symmetric, but the underlying matrix does not necessarily need to be.
* The block structure is symmetric, but the underlying matrix does not
* necessarily need to be.
*
* This class also has a parameter that can be changed after construction to change the apparent
* matrix view. firstBlock() determines the block that appears to have index 0 for all operations
* (except re-setting firstBlock()).
* This class also has a parameter that can be changed after construction to
* change the apparent matrix view. firstBlock() determines the block that
* appears to have index 0 for all operations (except re-setting firstBlock).
*
* @addtogroup base */
class GTSAM_EXPORT SymmetricBlockMatrix
{
class GTSAM_EXPORT SymmetricBlockMatrix {
public:
typedef SymmetricBlockMatrix This;
typedef SymmetricBlockMatrixBlockExpr<This> Block;
typedef SymmetricBlockMatrixBlockExpr<const This> constBlock;
protected:
Matrix matrix_; ///< The full matrix
FastVector<DenseIndex> variableColOffsets_; ///< the starting columns of each block (0-based)
DenseIndex blockStart_; ///< Changes apparent matrix view, see main class comment.
Matrix matrix_; ///< The full matrix
/// the starting columns of each block (0-based)
FastVector<DenseIndex> variableColOffsets_;
/// Changes apparent matrix view, see main class comment.
DenseIndex blockStart_;
public:
/// Construct from an empty matrix (asserts that the matrix is empty)
SymmetricBlockMatrix() :
blockStart_(0)
{
blockStart_(0) {
variableColOffsets_.push_back(0);
assertInvariants();
}
@ -62,8 +66,7 @@ namespace gtsam {
/// Construct from a container of the sizes of each block.
template<typename CONTAINER>
SymmetricBlockMatrix(const CONTAINER& dimensions) :
blockStart_(0)
{
blockStart_(0) {
fillOffsets(dimensions.begin(), dimensions.end());
matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
assertInvariants();
@ -72,142 +75,195 @@ namespace gtsam {
/// Construct from iterator over the sizes of each vertical block.
template<typename ITERATOR>
SymmetricBlockMatrix(ITERATOR firstBlockDim, ITERATOR lastBlockDim) :
blockStart_(0)
{
blockStart_(0) {
fillOffsets(firstBlockDim, lastBlockDim);
matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
assertInvariants();
}
/// Construct from a container of the sizes of each vertical block and a pre-prepared matrix.
/**
* @brief Construct from a container of the sizes of each vertical block
* and a pre-prepared matrix.
*/
template<typename CONTAINER>
SymmetricBlockMatrix(const CONTAINER& dimensions, const Matrix& matrix) :
blockStart_(0)
{
blockStart_(0) {
matrix_.resize(matrix.rows(), matrix.cols());
matrix_.triangularView<Eigen::Upper>() = matrix.triangularView<Eigen::Upper>();
matrix_.triangularView<Eigen::Upper>() =
matrix.triangularView<Eigen::Upper>();
fillOffsets(dimensions.begin(), dimensions.end());
if (matrix_.rows() != matrix_.cols())
throw std::invalid_argument("Requested to create a SymmetricBlockMatrix from a non-square matrix.");
throw std::invalid_argument("Requested to create a SymmetricBlockMatrix"
" from a non-square matrix.");
if (variableColOffsets_.back() != matrix_.cols())
throw std::invalid_argument("Requested to create a SymmetricBlockMatrix with dimensions that do not sum to the total size of the provided matrix.");
throw std::invalid_argument(
"Requested to create a SymmetricBlockMatrix with dimensions "
"that do not sum to the total size of the provided matrix.");
assertInvariants();
}
/// Copy the block structure, but do not copy the matrix data. If blockStart() has been
/// modified, this copies the structure of the corresponding matrix view. In the destination
/// SymmetricBlockMatrix, blockStart() will be 0.
static SymmetricBlockMatrix LikeActiveViewOf(const SymmetricBlockMatrix& other);
/**
* Copy the block structure, but do not copy the matrix data. If blockStart()
* has been modified, this copies the structure of the corresponding matrix.
* In the destination SymmetricBlockMatrix, blockStart() will be 0.
*/
static SymmetricBlockMatrix LikeActiveViewOf(
const SymmetricBlockMatrix& other);
/// Copy the block structure, but do not copy the matrix data. If blockStart() has been
/// modified, this copies the structure of the corresponding matrix view. In the destination
/// SymmetricBlockMatrix, blockStart() will be 0.
static SymmetricBlockMatrix LikeActiveViewOf(const VerticalBlockMatrix& other);
/**
* Copy the block structure, but do not copy the matrix data. If blockStart()
* has been modified, this copies the structure of the corresponding matrix.
* In the destination SymmetricBlockMatrix, blockStart() will be 0.
*/
static SymmetricBlockMatrix LikeActiveViewOf(
const VerticalBlockMatrix& other);
/// Row size
DenseIndex rows() const { assertInvariants(); return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
DenseIndex rows() const {
assertInvariants();
return variableColOffsets_.back() - variableColOffsets_[blockStart_];
}
/// Column size
DenseIndex cols() const { return rows(); }
DenseIndex cols() const {
return rows();
}
/// Block count
DenseIndex nBlocks() const { assertInvariants(); return variableColOffsets_.size() - 1 - blockStart_; }
DenseIndex nBlocks() const {
assertInvariants();
return variableColOffsets_.size() - 1 - blockStart_;
}
/// Access the block with vertical block index \c i_block and horizontal block index \c j_block.
/// Note that the actual block accessed in the underlying matrix is relative to blockStart().
/**
* Access the block with vertical block index \c i_block and horizontal block
* index \c j_block. Note that the actual block accessed in the underlying
* matrix is relative to blockStart().
*/
Block operator()(DenseIndex i_block, DenseIndex j_block) {
return Block(*this, i_block, j_block);
}
/// Access the block with vertical block index \c i_block and horizontal block index \c j_block.
/// Note that the actual block accessed in the underlying matrix is relative to blockStart().
/**
* Access the block with vertical block index \c i_block and horizontal block
* index \c j_block. Note that the actual block accessed in the underlying
* matrix is relative to blockStart().
*/
constBlock operator()(DenseIndex i_block, DenseIndex j_block) const {
return constBlock(*this, i_block, j_block);
}
/// Access the range of blocks starting with vertical block index \c i_startBlock, ending with
/// vertical block index \c i_endBlock, starting with horizontal block index \c j_startBlock,
/// and ending with horizontal block index \c j_endBlock. End block indices are exclusive. Note
/// that the actual blocks accessed in the underlying matrix are relative to blockStart().
Block range(DenseIndex i_startBlock, DenseIndex i_endBlock, DenseIndex j_startBlock, DenseIndex j_endBlock) {
/**
* Access the range of blocks starting with vertical block index
* \c i_startBlock, ending with vertical block index \c i_endBlock, starting
* with horizontal block index \c j_startBlock, and ending with horizontal
* block index \c j_endBlock. End block indices are exclusive. Note that the
* actual blocks accessed in the underlying matrix are relative to blockStart().
*/
Block range(DenseIndex i_startBlock, DenseIndex i_endBlock,
DenseIndex j_startBlock, DenseIndex j_endBlock) {
assertInvariants();
return Block(*this, i_startBlock, j_startBlock, i_endBlock - i_startBlock, j_endBlock - j_startBlock);
return Block(*this, i_startBlock, j_startBlock, i_endBlock - i_startBlock,
j_endBlock - j_startBlock);
}
/// Access the range of blocks starting with vertical block index \c i_startBlock, ending with
/// vertical block index \c i_endBlock, starting with horizontal block index \c j_startBlock,
/// and ending with horizontal block index \c j_endBlock. End block indices are exclusive. Note
/// that the actual blocks accessed in the underlying matrix are relative to blockStart().
constBlock range(DenseIndex i_startBlock, DenseIndex i_endBlock, DenseIndex j_startBlock, DenseIndex j_endBlock) const {
/**
* Access the range of blocks starting with vertical block index
* \c i_startBlock, ending with vertical block index \c i_endBlock, starting
* with horizontal block index \c j_startBlock, and ending with horizontal
* block index \c j_endBlock. End block indices are exclusive. Note that the
* actual blocks accessed in the underlying matrix are relative to blockStart().
*/
constBlock range(DenseIndex i_startBlock, DenseIndex i_endBlock,
DenseIndex j_startBlock, DenseIndex j_endBlock) const {
assertInvariants();
return constBlock(*this, i_startBlock, j_startBlock, i_endBlock - i_startBlock, j_endBlock - j_startBlock);
return constBlock(*this, i_startBlock, j_startBlock,
i_endBlock - i_startBlock, j_endBlock - j_startBlock);
}
/** Return the full matrix, *not* including any portions excluded by firstBlock(). */
Block full()
{
/**
* Return the full matrix, *not* including any portions excluded by
* firstBlock().
*/
Block full() {
return Block(*this, 0, nBlocks(), 0);
}
/** Return the full matrix, *not* including any portions excluded by firstBlock(). */
constBlock full() const
{
/**
* Return the full matrix, *not* including any portions excluded by
* firstBlock().
*/
constBlock full() const {
return constBlock(*this, 0, nBlocks(), 0);
}
/** Access to full matrix, including any portions excluded by firstBlock() to other operations. */
Eigen::SelfAdjointView<const Matrix, Eigen::Upper> matrix() const
{
/**
* Access to full matrix, including any portions excluded by firstBlock()
* to other operations.
*/
Eigen::SelfAdjointView<const Matrix, Eigen::Upper> matrix() const {
return matrix_;
}
/** Access to full matrix, including any portions excluded by firstBlock() to other operations. */
Eigen::SelfAdjointView<Matrix, Eigen::Upper> matrix()
{
/** Access to full matrix, including any portions excluded by firstBlock()
* to other operations.
*/
Eigen::SelfAdjointView<Matrix, Eigen::Upper> matrix() {
return matrix_;
}
/// Return the absolute offset in the underlying matrix of the start of the specified \c block.
DenseIndex offset(DenseIndex block) const
{
/**
* Return the absolute offset in the underlying matrix
* of the start of the specified \c block.
*/
DenseIndex offset(DenseIndex block) const {
assertInvariants();
DenseIndex actualBlock = block + blockStart_;
checkBlock(actualBlock);
return variableColOffsets_[actualBlock];
}
/// Retrieve or modify the first logical block, i.e. the block referenced by block index 0.
/// Blocks before it will be inaccessible, except by accessing the underlying matrix using
/// matrix().
DenseIndex& blockStart() { return blockStart_; }
/**
* Retrieve or modify the first logical block, i.e. the block referenced by
* block index 0. Blocks before it will be inaccessible, except by accessing
* the underlying matrix using matrix().
*/
DenseIndex& blockStart() {
return blockStart_;
}
/// Retrieve the first logical block, i.e. the block referenced by block index 0. Blocks before
/// it will be inaccessible, except by accessing the underlying matrix using matrix().
DenseIndex blockStart() const { return blockStart_; }
/**
* Retrieve the first logical block, i.e. the block referenced by block index 0.
* Blocks before it will be inaccessible, except by accessing the underlying
* matrix using matrix().
*/
DenseIndex blockStart() const {
return blockStart_;
}
/// Do partial Cholesky in-place and return the eliminated block matrix, leaving the remaining
/// symmetric matrix in place.
/**
* Do partial Cholesky in-place and return the eliminated block matrix,
* leaving the remaining symmetric matrix in place.
*/
VerticalBlockMatrix choleskyPartial(DenseIndex nFrontals);
protected:
void assertInvariants() const
{
void assertInvariants() const {
assert(matrix_.rows() == matrix_.cols());
assert(matrix_.cols() == variableColOffsets_.back());
assert(blockStart_ < (DenseIndex)variableColOffsets_.size());
}
void checkBlock(DenseIndex block) const
{
void checkBlock(DenseIndex block) const {
assert(matrix_.rows() == matrix_.cols());
assert(matrix_.cols() == variableColOffsets_.back());
assert(block >= 0);
assert(block < (DenseIndex)variableColOffsets_.size()-1);
assert(variableColOffsets_[block] < matrix_.cols() && variableColOffsets_[block+1] <= matrix_.cols());
assert(
variableColOffsets_[block] < matrix_.cols() && variableColOffsets_[block+1] <= matrix_.cols());
}
DenseIndex offsetUnchecked(DenseIndex block) const
{
DenseIndex offsetUnchecked(DenseIndex block) const {
return variableColOffsets_[block + blockStart_];
}
@ -281,8 +337,7 @@ namespace gtsam {
//}
template<typename ITERATOR>
void fillOffsets(ITERATOR firstBlockDim, ITERATOR lastBlockDim)
{
void fillOffsets(ITERATOR firstBlockDim, ITERATOR lastBlockDim) {
variableColOffsets_.resize((lastBlockDim - firstBlockDim) + 1);
variableColOffsets_[0] = 0;
DenseIndex j = 0;
@ -307,12 +362,13 @@ namespace gtsam {
};
/* ************************************************************************* */
class CholeskyFailed : public gtsam::ThreadsafeException<CholeskyFailed>
{
class CholeskyFailed: public gtsam::ThreadsafeException<CholeskyFailed> {
public:
CholeskyFailed() throw() {}
virtual ~CholeskyFailed() throw() {}
CholeskyFailed() throw () {
}
virtual ~CholeskyFailed() throw () {
}
};
}
} //\ namespace gtsam