GQCP
Loading...
Searching...
No Matches
ImplicitMatrixSlice.hpp
Go to the documentation of this file.
1// This file is part of GQCG-GQCP.
2//
3// Copyright (C) 2017-2020 the GQCG developers
4//
5// GQCG-GQCP is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GQCG-GQCP is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GQCG-GQCP. If not, see <http://www.gnu.org/licenses/>.
17
18#pragma once
19
20
22
23#include <map>
24#include <numeric>
25
26
27namespace GQCP {
28
29
37template <typename _Scalar>
39public:
40 using Scalar = _Scalar;
41
42
43private:
44 std::map<size_t, size_t> rows_implicit_to_dense; // maps the row indices of the implicit matrix to the row indices of the dense representation of the slice
45 std::map<size_t, size_t> cols_implicit_to_dense; // maps the column indices of the implicit matrix to the column indices of the dense representation of the slice
46
47 MatrixX<Scalar> M; // the dense representation of the slice
48
49
50public:
51 /*
52 * CONSTRUCTORS
53 */
54
62 ImplicitMatrixSlice(const std::map<size_t, size_t>& rows_implicit_to_dense, const std::map<size_t, size_t>& cols_implicit_to_dense, const MatrixX<Scalar>& M) :
63 rows_implicit_to_dense {rows_implicit_to_dense},
64 cols_implicit_to_dense {cols_implicit_to_dense},
65 M {M} {
66
67 // Check if the maps are consistent with the dense representation of the slice.
68 if (this->rows_implicit_to_dense.size() != this->M.rows()) {
69 throw std::invalid_argument("ImplicitMatrixSlice(const std::map<size_t, size_t>&, const std::map<size_t, size_t>&, const MatrixX<Scalar>&): The given dense representation of the slice does not have a compatible number of rows.");
70 }
71
72 if (this->cols_implicit_to_dense.size() != this->M.cols()) {
73 throw std::invalid_argument("ImplicitMatrixSlice(const std::map<size_t, size_t>&, const std::map<size_t, size_t>&, const MatrixX<Scalar>&): The given dense representation of the slice does not have a compatible number of columns.");
74 }
75 }
76
77
84 ImplicitMatrixSlice(const std::map<size_t, size_t>& rows_implicit_to_dense, const std::map<size_t, size_t>& cols_implicit_to_dense) :
85 ImplicitMatrixSlice(rows_implicit_to_dense, cols_implicit_to_dense,
86 MatrixX<Scalar>::Zero(rows_implicit_to_dense.size(), cols_implicit_to_dense.size())) {}
87
88
93 // Use a named constructor for the default initialization.
95
96
97 /*
98 * NAMED CONSTRUCTORS
99 */
100
112 static ImplicitMatrixSlice<Scalar> FromBlockRanges(const size_t row_start, const size_t row_end, const size_t col_start, const size_t col_end, const MatrixX<Scalar>& M) {
113
114 // Convert the ranges into allowed row and column indices of the implicit matrix, and then use another named constructor.
115 std::vector<size_t> row_indices(row_end - row_start);
116 std::iota(row_indices.begin(), row_indices.end(), row_start);
117
118 std::vector<size_t> col_indices(col_end - col_start);
119 std::iota(col_indices.begin(), col_indices.end(), col_start);
120
121 return ImplicitMatrixSlice<Scalar>::FromIndices(row_indices, col_indices, M);
122 }
123
124
134 static ImplicitMatrixSlice<Scalar> FromIndices(const std::vector<size_t>& row_indices, const std::vector<size_t>& col_indices, const MatrixX<Scalar>& M) {
135
136 // Loop over all row and column indices, mapping them to the indices of the dense representation of the slice.
137 std::map<size_t, size_t> rows_map;
138 size_t dense_row_index = 0; // row index in the dense representation of the slice
139 for (const auto& implicit_row_index : row_indices) {
140
141 rows_map[implicit_row_index] = dense_row_index;
142 dense_row_index++; // the dense indices are contiguous
143 }
144
145 std::map<size_t, size_t> cols_map;
146 size_t dense_col_index = 0; // column index in the dense representation of the slice
147 for (const auto& implicit_col_index : col_indices) {
148
149 cols_map[implicit_col_index] = dense_col_index;
150 dense_col_index++; // the dense indices are contiguous
151 }
152
153 return ImplicitMatrixSlice<Scalar>(rows_map, cols_map, M);
154 }
155
156
168 static ImplicitMatrixSlice<Scalar> ZeroFromBlockRanges(const size_t row_start, const size_t row_end, const size_t col_start, const size_t col_end) {
169
170 // Create the zero dense representation of the slice and then use another named constructor.
171 const auto rows = row_end - row_start;
172 const auto cols = col_end - col_start;
173 const MatrixX<Scalar> M = MatrixX<Scalar>::Zero(rows, cols);
174
175 return ImplicitMatrixSlice<Scalar>::FromBlockRanges(row_start, row_end, col_start, col_end, M);
176 }
177
178
187 static ImplicitMatrixSlice<Scalar> ZeroFromIndices(const std::vector<size_t>& row_indices, const std::vector<size_t>& col_indices) {
188
189 // Zero-initialize a matrix with the number of rows and columns and use a different constructor.
190 const MatrixX<Scalar> M = MatrixX<Scalar>::Zero(row_indices.size(), col_indices.size());
191
192 return ImplicitMatrixSlice<Scalar>::FromIndices(row_indices, col_indices, M);
193 }
194
195
196 /*
197 * OPERATORS
198 */
199
208 Scalar operator()(const size_t row, const size_t col) const {
209
210 // Map the implicit row and column indices to the row and column indices of the dense representation of this slice and access accordingly.
211 const size_t i = this->denseIndexOfRow(row);
212 const size_t j = this->denseIndexOfColumn(col);
213
214 return this->M(i, j);
215 }
216
217
226 Scalar& operator()(const size_t row, const size_t col) {
227
228 // Map the implicit row and column indices to the row and column indices of the dense representation of this slice and access accordingly.
229 const size_t i = this->denseIndexOfRow(row);
230 const size_t j = this->denseIndexOfColumn(col);
231
232 return this->M(i, j);
233 }
234
235
236 /*
237 * PUBLIC METHODS
238 */
239
243 const MatrixX<Scalar>& asMatrix() const { return this->M; }
244
248 VectorX<Scalar> asVector() const { return this->M.pairWiseReduced(); }
249
253 const std::map<size_t, size_t>& columnIndexMap() const { return this->cols_implicit_to_dense; }
254
262 size_t denseIndexOfColumn(const size_t col) const { return this->cols_implicit_to_dense.at(col); }
263
271 size_t denseIndexOfRow(const size_t row) const { return this->rows_implicit_to_dense.at(row); }
272
276 const std::map<size_t, size_t>& rowIndexMap() const { return this->rows_implicit_to_dense; }
277};
278
279
280} // namespace GQCP
Definition: ImplicitMatrixSlice.hpp:38
static ImplicitMatrixSlice< Scalar > ZeroFromIndices(const std::vector< size_t > &row_indices, const std::vector< size_t > &col_indices)
Definition: ImplicitMatrixSlice.hpp:187
ImplicitMatrixSlice(const std::map< size_t, size_t > &rows_implicit_to_dense, const std::map< size_t, size_t > &cols_implicit_to_dense)
Definition: ImplicitMatrixSlice.hpp:84
const MatrixX< Scalar > & asMatrix() const
Definition: ImplicitMatrixSlice.hpp:243
VectorX< Scalar > asVector() const
Definition: ImplicitMatrixSlice.hpp:248
static ImplicitMatrixSlice< Scalar > FromBlockRanges(const size_t row_start, const size_t row_end, const size_t col_start, const size_t col_end, const MatrixX< Scalar > &M)
Definition: ImplicitMatrixSlice.hpp:112
Scalar operator()(const size_t row, const size_t col) const
Definition: ImplicitMatrixSlice.hpp:208
Scalar & operator()(const size_t row, const size_t col)
Definition: ImplicitMatrixSlice.hpp:226
_Scalar Scalar
Definition: ImplicitMatrixSlice.hpp:40
static ImplicitMatrixSlice< Scalar > ZeroFromBlockRanges(const size_t row_start, const size_t row_end, const size_t col_start, const size_t col_end)
Definition: ImplicitMatrixSlice.hpp:168
size_t denseIndexOfColumn(const size_t col) const
Definition: ImplicitMatrixSlice.hpp:262
const std::map< size_t, size_t > & columnIndexMap() const
Definition: ImplicitMatrixSlice.hpp:253
static ImplicitMatrixSlice< Scalar > FromIndices(const std::vector< size_t > &row_indices, const std::vector< size_t > &col_indices, const MatrixX< Scalar > &M)
Definition: ImplicitMatrixSlice.hpp:134
const std::map< size_t, size_t > & rowIndexMap() const
Definition: ImplicitMatrixSlice.hpp:276
size_t denseIndexOfRow(const size_t row) const
Definition: ImplicitMatrixSlice.hpp:271
ImplicitMatrixSlice()
Definition: ImplicitMatrixSlice.hpp:92
ImplicitMatrixSlice(const std::map< size_t, size_t > &rows_implicit_to_dense, const std::map< size_t, size_t > &cols_implicit_to_dense, const MatrixX< Scalar > &M)
Definition: ImplicitMatrixSlice.hpp:62
Definition: Matrix.hpp:47
Definition: BaseOneElectronIntegralBuffer.hpp:25