BlockDiagonalMatrix
Simple full matrix container
The `BlockDiagonalMatrix` manages matrices with non-zero elements in blocks along the diagonal, supporting efficient linear algebra operations within SOFA simulations.
- module
- Sofa.framework.LinearAlgebra
- namespace
- sofa::linearalgebra
- include
- sofa/linearalgebra/BlockDiagonalMatrix.h
- inherits
-
- BaseMatrix
- templates
-
- 3, SReal
- description
Mathematical Description
The BlockDiagonalMatrix is a specialized data structure used to represent matrices where the non-zero elements are concentrated in blocks along the main diagonal. This class inherits from the more general BaseMatrix, which provides a framework for matrix operations within the SOFA simulation framework.
Structure and Representation
A block diagonal matrix can be represented as:
$$ M = \begin{pmatrix} B_1 & 0 & \cdots & 0 \\ 0 & B_2 & \ddots & \vdots \\ \vdots & \ddots & \ddots & 0 \\ 0 & \cdots & 0 & B_n \end{pmatrix} $$where each $B_i$ is a square submatrix (block) and the rest of the matrix elements are zero.
Block Size Parameterization
The BlockDiagonalMatrix class allows for different block sizes, parameterized by a template argument LC. Common instantiations include BlockDiagonalMatrix3, BlockDiagonalMatrix6, etc., which represent matrices with 3x3 and 6x6 blocks along the diagonal.
Element Access and Manipulation
-
Element Access: The method
element(Index i, Index j)retrieves the element at row $i$ and column $j$. For a block diagonal matrix, this element is non-zero only if both $i$ and $j$ belong to the same block. -
Set Operation: The
set(Index i, Index j, Real value)method sets the value of an element. If $i$ and $j$ do not correspond to a position within one of the blocks, setting the value will effectively have no effect since that element is always zero. -
Addition: The
add(Index i, Index j, Real value)method adds a specified value to an existing element at row $i$, column $j$. This operation affects only the elements within the defined block structure.
Block Operations
The class provides methods for operating on entire blocks rather than individual elements:
-
Block Access: The
bloc(Index b)method retrieves the submatrix (block) located at position $b$ along the diagonal. -
Clearing Blocks: Methods like
clear(Index i, Index j),clearRow(Index i), andclearCol(Index j)are provided to reset individual elements or entire rows/columns within a block. Clearing an element outside of its block simply sets it to zero without affecting the matrix structure.
Matrix Operations
-
Matrix-Vector Multiplication: The method
mul(FullVector<Real2>& res, const FullVector<Real2>& v)computes the product $Mv$, where $M$ is the block diagonal matrix and $v$ is a vector. This operation exploits the structure of $M$ to perform efficient computations by only considering non-zero blocks. -
Inversion: The
invert()method inverts each block individually, assuming that all blocks are square and invertible:
Each block $B_i$ is inverted separately, and the resulting matrix is also block diagonal.
Physical Description
In the context of physical simulations, particularly within SOFA (Simulation Open Framework Architecture), BlockDiagonalMatrix can be used to efficiently handle matrices that arise from systems with localized interactions. For example:
-
Multi-resolution Models: In multi-resolution models where different levels of detail are represented by blocks of varying sizes, the block diagonal structure allows for efficient computation at each resolution level.
-
Localized Interactions: When simulating systems where particles or elements interact primarily within their local neighborhood (e.g., certain types of finite element simulations), using a block diagonal matrix can significantly reduce computational overhead by focusing computations on relevant submatrices rather than the entire system matrix.
By leveraging this data structure, SOFA simulations can achieve better performance and scalability when dealing with complex systems that exhibit localized or hierarchical interactions.
Methods
void
resize
(Index nbRow, Index )
virtual
Index
rowSize
()
virtual
Index
colSize
()
virtual
Index
rowBSize
()
Index
colBSize
()
const Block &
bloc
(Index i)
const Block &
bloc
(Index i, Index j)
Block *
wbloc
(Index i)
Block *
wbloc
(Index i, Index j)
SReal
element
(Index i, Index j)
virtual
void
set
(Index i, Index j, double v)
virtual
void
setB
(Index i, const Block & b)
void
setB
(Index i, Index j, const Block & b)
void
add
(Index i, Index j, double v)
virtual
void
addB
(Index i, const Block & b)
void
addB
(Index i, Index j, const Block & b)
void
clear
(Index i, Index j)
virtual
void
clearRow
(Index i)
virtual
void
clearCol
(Index j)
virtual
void
clearRowCol
(Index i)
virtual
void
clear
()
virtual
void
invert
()
void
mul
(FullVector<Real2> & res, const FullVector<Real2> & v)
FullVector<Real2>
operator*
(const FullVector<Real2> & v)
const char *
Name
()
{
"name": "BlockDiagonalMatrix",
"namespace": "sofa::linearalgebra",
"module": "Sofa.framework.LinearAlgebra",
"include": "sofa/linearalgebra/BlockDiagonalMatrix.h",
"doc": "Simple full matrix container",
"inherits": [
"BaseMatrix"
],
"templates": [
"3, SReal"
],
"data_fields": [],
"links": [],
"methods": [
{
"name": "resize",
"return_type": "void",
"params": [
{
"name": "nbRow",
"type": "Index"
},
{
"name": "",
"type": "Index"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "rowSize",
"return_type": "Index",
"params": [],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "colSize",
"return_type": "Index",
"params": [],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "rowBSize",
"return_type": "Index",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "colBSize",
"return_type": "Index",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "bloc",
"return_type": "const Block &",
"params": [
{
"name": "i",
"type": "Index"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "bloc",
"return_type": "const Block &",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "wbloc",
"return_type": "Block *",
"params": [
{
"name": "i",
"type": "Index"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "wbloc",
"return_type": "Block *",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "element",
"return_type": "SReal",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "set",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
},
{
"name": "v",
"type": "double"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "setB",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "b",
"type": "const Block &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "setB",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
},
{
"name": "b",
"type": "const Block &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "add",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
},
{
"name": "v",
"type": "double"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "addB",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "b",
"type": "const Block &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "addB",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
},
{
"name": "b",
"type": "const Block &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "clear",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
},
{
"name": "j",
"type": "Index"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "clearRow",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "clearCol",
"return_type": "void",
"params": [
{
"name": "j",
"type": "Index"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "clearRowCol",
"return_type": "void",
"params": [
{
"name": "i",
"type": "Index"
}
],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "clear",
"return_type": "void",
"params": [],
"is_virtual": true,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "invert",
"return_type": "void",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "mul",
"return_type": "void",
"params": [
{
"name": "res",
"type": "FullVector<Real2> &"
},
{
"name": "v",
"type": "const FullVector<Real2> &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "operator*",
"return_type": "FullVector<Real2>",
"params": [
{
"name": "v",
"type": "const FullVector<Real2> &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "Name",
"return_type": "const char *",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": true,
"access": "public"
}
],
"description": "The `BlockDiagonalMatrix` is part of the SOFA framework's LinearAlgebra module and inherits from `BaseMatrix`. This class provides functionality for managing block diagonal matrices in simulations. A block diagonal matrix consists of submatrices (blocks) along its main diagonal, with all other elements being zero.\n\n### Role and Purpose\nIn the context of SOFA, `BlockDiagonalMatrix` is used to handle specific linear algebra operations that are optimized for matrices where non-zero entries are confined to blocks along the diagonal. This structure is often useful in simulations involving multi-resolution models or systems with localized interactions.\n\n### Interactions with Other Components\nThe component interacts with other components through its virtual methods inherited from `BaseMatrix`, allowing it to integrate seamlessly into broader linear algebra workflows within SOFA. It supports resizing, element-wise access (get and set), matrix-vector multiplication (`mul`), and inversion operations. The API enables the addition of elements or blocks and clearing of rows, columns, or individual entries.\n\n### Practical Usage Guidance\n- **Resizing**: Use `resize()` to adjust the size of the matrix based on the number of rows (columns are automatically aligned).\n- **Element Access**: Methods like `element()`, `set()`, and `add()` allow manipulation of individual elements within blocks.\n- **Block Operations**: Functions such as `bloc()`, `wbloc()`, `setB()`, and `addB()` facilitate operations on entire blocks rather than single elements.\n- **Matrix Operations**: Methods like `mul()` for matrix-vector multiplication and `invert()` for inverting the matrix are provided.\n\nThe component is templated, allowing different block sizes (e.g., 3x3) to be used as needed. This flexibility makes it suitable for various simulation scenarios where block diagonal matrices can optimize performance.",
"maths": "### Mathematical Description\n\nThe `BlockDiagonalMatrix` is a specialized data structure used to represent matrices where the non-zero elements are concentrated in blocks along the main diagonal. This class inherits from the more general `BaseMatrix`, which provides a framework for matrix operations within the SOFA simulation framework.\n\n#### Structure and Representation\n\nA block diagonal matrix can be represented as:\n\\[\n M = \\begin{pmatrix}\n B_1 & 0 & \\cdots & 0 \\\\\n 0 & B_2 & \\ddots & \\vdots \\\\\n \\vdots & \\ddots & \\ddots & 0 \\\\\n 0 & \\cdots & 0 & B_n\n \\end{pmatrix}\n\\]\nwhere each $B_i$ is a square submatrix (block) and the rest of the matrix elements are zero.\n\n#### Block Size Parameterization\n\nThe `BlockDiagonalMatrix` class allows for different block sizes, parameterized by a template argument `LC`. Common instantiations include `BlockDiagonalMatrix3`, `BlockDiagonalMatrix6`, etc., which represent matrices with 3x3 and 6x6 blocks along the diagonal.\n\n#### Element Access and Manipulation\n\n- **Element Access**: The method `element(Index i, Index j)` retrieves the element at row $i$ and column $j$. For a block diagonal matrix, this element is non-zero only if both $i$ and $j$ belong to the same block.\n\n- **Set Operation**: The `set(Index i, Index j, Real value)` method sets the value of an element. If $i$ and $j$ do not correspond to a position within one of the blocks, setting the value will effectively have no effect since that element is always zero.\n\n- **Addition**: The `add(Index i, Index j, Real value)` method adds a specified value to an existing element at row $i$, column $j$. This operation affects only the elements within the defined block structure.\n\n#### Block Operations\n\nThe class provides methods for operating on entire blocks rather than individual elements:\n\n- **Block Access**: The `bloc(Index b)` method retrieves the submatrix (block) located at position $b$ along the diagonal.\n\n- **Clearing Blocks**: Methods like `clear(Index i, Index j)`, `clearRow(Index i)`, and `clearCol(Index j)` are provided to reset individual elements or entire rows/columns within a block. Clearing an element outside of its block simply sets it to zero without affecting the matrix structure.\n\n#### Matrix Operations\n\n- **Matrix-Vector Multiplication**: The method `mul(FullVector<Real2>& res, const FullVector<Real2>& v)` computes the product $Mv$, where $M$ is the block diagonal matrix and $v$ is a vector. This operation exploits the structure of $M$ to perform efficient computations by only considering non-zero blocks.\n\n- **Inversion**: The `invert()` method inverts each block individually, assuming that all blocks are square and invertible:\n\\[\n M^{-1} = \\begin{pmatrix}\n B_1^{-1} & 0 & \\cdots & 0 \\\\\n 0 & B_2^{-1} & \\ddots & \\vdots \\\\\n \\vdots & \\ddds & \\ddots & 0 \\\\\n 0 & \\cdots & 0 & B_n^{-1}\n \\end{pmatrix}\n\\]\nEach block $B_i$ is inverted separately, and the resulting matrix is also block diagonal.\n\n### Physical Description\n\nIn the context of physical simulations, particularly within SOFA (Simulation Open Framework Architecture), `BlockDiagonalMatrix` can be used to efficiently handle matrices that arise from systems with localized interactions. For example:\n\n- **Multi-resolution Models**: In multi-resolution models where different levels of detail are represented by blocks of varying sizes, the block diagonal structure allows for efficient computation at each resolution level.\n\n- **Localized Interactions**: When simulating systems where particles or elements interact primarily within their local neighborhood (e.g., certain types of finite element simulations), using a block diagonal matrix can significantly reduce computational overhead by focusing computations on relevant submatrices rather than the entire system matrix.\n\nBy leveraging this data structure, SOFA simulations can achieve better performance and scalability when dealing with complex systems that exhibit localized or hierarchical interactions.",
"abstract": "The `BlockDiagonalMatrix` manages matrices with non-zero elements in blocks along the diagonal, supporting efficient linear algebra operations within SOFA simulations.",
"sheet": "# BlockDiagonalMatrix\n\n## Overview\n\nThe `BlockDiagonalMatrix` is a specialized matrix container designed to handle block diagonal matrices where non-zero elements are concentrated in submatrices (blocks) along the main diagonal. This class inherits from `BaseMatrix`, providing methods for resizing, element-wise access and manipulation, block operations, and matrix-vector multiplication.\n\n## Mathematical Model\n\nA block diagonal matrix can be represented as:\n\n\begin{equation}\n M = \\begin{pmatrix}\n B_1 & 0 & \\cdots & 0 \\\\\n 0 & B_2 & \\ddots & \\vdots \\\\\n \\vdots & \\ddots & \\ddots & 0 \\\\\n 0 & \\cdots & 0 & B_n\n \\end{pmatrix}\n\\end{equation}\n\nwhere each $B_i$ is a square submatrix (block) and the rest of the matrix elements are zero.\n\n### Element Access and Manipulation\n\n- **Element Access**: The method `element(Index i, Index j)` retrieves the element at row $i$ and column $j$. For a block diagonal matrix, this element is non-zero only if both $i$ and $j$ belong to the same block.\n\n- **Set Operation**: The `set(Index i, Index j, Real value)` method sets the value of an element. If $i$ and $j$ do not correspond to a position within one of the blocks, setting the value will effectively have no effect since that element is always zero.\n\n### Block Operations\n\n- **Block Access**: The `bloc(Index b)` method retrieves the submatrix (block) located at position $b$ along the diagonal.\n\n- **Clearing Blocks**: Methods like `clear(Index i, Index j)`, `clearRow(Index i)`, and `clearCol(Index j)` are provided to reset individual elements or entire rows/columns within a block. Clearing an element outside of its block simply sets it to zero without affecting the matrix structure.\n\n### Matrix Operations\n\n- **Matrix-Vector Multiplication**: The method `mul(FullVector<Real2>& res, const FullVector<Real2>& v)` computes the product $Mv$, where $M$ is the block diagonal matrix and $v$ is a vector. This operation exploits the structure of $M$ to perform efficient computations by only considering non-zero blocks.\n\n- **Inversion**: The `invert()` method inverts each block individually, assuming that all blocks are square and invertible:\n\n\begin{equation}\n M^{-1} = \\begin{pmatrix}\n B_1^{-1} & 0 & \\cdots & 0 \\\\\n 0 & B_2^{-1} & \\ddots & \\vdots \\\\\n \\vdots & \\ddds & \\ddots & 0 \\\\\n 0 & \\cdots & 0 & B_n^{-1}\n \\end{pmatrix}\n\\end{equation}\n\nEach block $B_i$ is inverted separately, and the resulting matrix is also block diagonal."
}