RealTimeTransport 1.0.0
Real-time simulation of quantum transport processes
Loading...
Searching...
No Matches
BlockMatrix.h
1//
2// This Source Code Form is subject to the terms of the Mozilla Public
3// License, v. 2.0. If a copy of the MPL was not distributed with this
4// file, You can obtain one at https://mozilla.org/MPL/2.0/.
5//
6
7#ifndef REAL_TIME_TRANSPORT_BLOCK_MATRICES_BLOCK_MATRIX_H
8#define REAL_TIME_TRANSPORT_BLOCK_MATRICES_BLOCK_MATRIX_H
9
10#include <set>
11#include <vector>
12
13#include "../extern/boost_unordered.hpp"
14
15#include <SciCore/Definitions.h>
16
17#include "../Error.h"
18#include "../RealTimeTransport_export.h"
19#include "BlockHelper.h"
20
21namespace RealTimeTransport
22{
23
24// Represents a matrix separated into blocks, out of which most blocks are zero.
25class REALTIMETRANSPORT_EXPORT BlockMatrix
26{
27 public:
28 using Scalar = SciCore::Complex;
29 using MatrixType = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
30 using UnorderedElementMap = boost::unordered_flat_map<std::pair<int, int>, MatrixType>;
31
32 BlockMatrix() noexcept;
33 BlockMatrix(const std::vector<int>& blockDimensions);
34
35 template <SciCore::DenseMatrixType DenseMatrixT>
36 BlockMatrix(const DenseMatrixT& matrix, const std::vector<int>& blockDimensions)
37 {
38 fromDense(matrix, blockDimensions);
39 }
40
41 BlockMatrix(UnorderedElementMap&& elements, const std::vector<int>& blockDimensions);
42
43 BlockMatrix(BlockMatrix&& other) noexcept;
44 BlockMatrix(const BlockMatrix& other) noexcept;
45
46 BlockMatrix& operator=(BlockMatrix&& other);
47 BlockMatrix& operator=(const BlockMatrix& other);
48
49 BlockMatrix& operator*=(Scalar x);
50 const std::vector<int>& blockDimensions() const noexcept;
51
52 ///
53 /// @brief Returns the number of blocks of each row/column, i.e., the matrix separated is into numBlocks*numBlocks blocks.
54 ///
55 int numBlocks() const noexcept;
56
57 ///
58 /// @brief Returns the number of non-zero blocks.
59 ///
60 int size() const noexcept;
61
62 int totalRows() const noexcept;
63
64 int totalCols() const noexcept;
65
66 void fromUnorderedMap(UnorderedElementMap&& elements, const std::vector<int>& blockDimensions);
67
68 template <typename DenseMatrixT>
69 void fromDense(const DenseMatrixT& matrix, const std::vector<int>& blockDimensions)
70 {
71 _blockDims = blockDimensions;
72 int numBlocks = this->numBlocks();
73
74 _elements.clear();
75 _nonZeroRows.clear();
76 _nonZeroCols.clear();
77 _nonZeroRows.resize(numBlocks);
78 _nonZeroCols.resize(numBlocks);
79
80 // Partition the matrix into blocks and store them
81 for (int i = 0; i < numBlocks; ++i)
82 {
83 for (int j = 0; j < numBlocks; ++j)
84 {
85 MatrixType block = extractDenseBlock(matrix, i, j, blockDimensions);
86
87 if (block.isZero() == false)
88 {
89 _elements[{i, j}] = std::move(block);
90 _nonZeroRows[j].insert(i);
91 _nonZeroCols[i].insert(j);
92 }
93 }
94 }
95 }
96
97 MatrixType toDense() const;
98
99 // Get block at position (i, j)
100 const MatrixType& operator()(int i, int j) const;
101
102 void addToBlock(int i, int j, MatrixType&& A);
103
104 // Return true if the block at (i ,j) is not zero
105 bool contains(int i, int j) const noexcept;
106
107 const std::set<int>& nonZeroRows(int j) const;
108 const std::set<int>& nonZeroCols(int i) const;
109
110 UnorderedElementMap::iterator begin() noexcept;
111 UnorderedElementMap::iterator end() noexcept;
112 UnorderedElementMap::const_iterator begin() const noexcept;
113 UnorderedElementMap::const_iterator end() const noexcept;
114
115 UnorderedElementMap::const_iterator find(int i, int j) const;
116
117 private:
118 std::vector<int> _blockDims; // Dimensions of each block in the diagonal
119 UnorderedElementMap _elements; // Stores the blocks
120
121 // _nonZeroRows[j] contains indices i of rows such that the block i,j is not zero
122 std::vector<std::set<int>> _nonZeroRows;
123
124 // _nonZeroCols[i] contains indices j of columns such that the block i,j is not zero
125 std::vector<std::set<int>> _nonZeroCols;
126};
127
128// Computes result += alpha * A * x
129// The vector blockStartIndices should be computed as
130// const std::vector<int>& blockDims = A.blockDimensions();
131// std::vector<int> blockStartIndices(blockDims.size(), 0);
132// for (size_t i = 1; i < blockDims.size(); ++i)
133// {
134// blockStartIndices[i] = blockStartIndices[i - 1] + blockDims[i - 1];
135// }
136REALTIMETRANSPORT_EXPORT void addProduct(
137 SciCore::Complex alpha,
138 const BlockMatrix& A,
139 const Eigen::Matrix<SciCore::Complex, Eigen::Dynamic, 1>& x,
140 Eigen::Matrix<SciCore::Complex, Eigen::Dynamic, 1>& result,
141 const std::vector<int>& blockStartIndices);
142
143REALTIMETRANSPORT_EXPORT void addProduct(
144 SciCore::Complex alpha,
145 const Eigen::Matrix<SciCore::Complex, 1, Eigen::Dynamic>& x,
146 const BlockMatrix& A,
147 Eigen::Matrix<SciCore::Complex, 1, Eigen::Dynamic>& result,
148 const std::vector<int>& blockStartIndices);
149
150// Returns alpha * x * A
151REALTIMETRANSPORT_EXPORT Eigen::Matrix<SciCore::Complex, 1, Eigen::Dynamic> product(
152 SciCore::Complex alpha,
153 const Eigen::Matrix<SciCore::Complex, 1, Eigen::Dynamic>& x,
154 const BlockMatrix& A,
155 const std::vector<int>& blockStartIndices);
156
157} // namespace RealTimeTransport
158
159#endif // REAL_TIME_TRANSPORT_BLOCK_MATRICES_BLOCK_MATRIX_H
#define REALTIMETRANSPORT_EXPORT
Definition RealTimeTransport_export.h:15