GQCP
Loading...
Searching...
No Matches
DenseVectorizer.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
21#include <stdexcept>
22
23#include <array>
24#include <cstddef>
25#include <numeric>
26
27
28namespace GQCP {
29
30
34enum class Ordering {
35 // Specifies that the first axis is contiguous.
37
38 // Specifies that the last axis is contiguous.
40};
41
42
48template <size_t A>
50private:
51 // The ordering of the axes.
52 Ordering m_ordering;
53
54 // The dimensions of each axis.
55 std::array<size_t, A> m_dimensions;
56
57 // The strides associated to each axis.
58 std::array<size_t, A> m_strides;
59
60
61public:
62 /*
63 * CONSTRUCTORS
64 */
65
72 DenseVectorizer(const std::array<size_t, A>& dimensions, const Ordering ordering = Ordering::ColumnMajor) :
73 m_ordering {ordering},
74 m_dimensions {dimensions} {
75
76 // Initialize the strides for every dimension.
77 switch (this->m_ordering) {
78 case Ordering::ColumnMajor: { // the first axis is contiguous
79 for (size_t k = 0; k < A; k++) {
80
81 size_t stride {1};
82 for (size_t l = 0; l < k; l++) {
83 stride *= this->m_dimensions[l];
84 }
85
86 this->m_strides[k] = stride;
87 }
88 break;
89 }
90
91 case Ordering::RowMajor: { // the last axis is contiguous
92 for (size_t k = 0; k < A; k++) {
93
94 size_t stride {1};
95 for (size_t l = k + 1; l < A; l++) {
96 stride *= this->m_dimensions[l];
97 }
98
99 this->m_strides[k] = stride;
100 }
101 break;
102 }
103 }
104 }
105
110 DenseVectorizer(std::array<size_t, A> {}) {}
111
112
124 size_t offset(const std::array<size_t, A>& indices) const {
125
126 size_t value {0};
127 for (size_t k = 0; k < A; k++) {
128 if (indices[k] > this->dimension(k)) {
129 throw std::invalid_argument("DenseVectorizer::offset(const std::array<size_t, A>&): The index is not supported with the memory layout.");
130 }
131
132 value += this->stride(k) * indices[k];
133 }
134
135 return value;
136 }
137
138
139 /*
140 * MARK: General information
141 */
142
148 size_t dimension(const size_t axis) const {
149 if (axis >= A) {
150 throw std::invalid_argument("DenseVectorizer::offset(const std::array<size_t, A>&): The given axis does not exist.");
151 }
152
153 return this->dimensions()[axis];
154 }
155
159 const std::array<size_t, A>& dimensions() const { return this->m_dimensions; }
160
161 // The number of axes for this vectorizer.
162 static constexpr auto NumberOfAxes = A;
163
167 size_t numberOfAxes() const { return A; }
168
172 size_t numberOfElements() const {
173 return std::accumulate(this->dimensions().begin(), this->dimensions().end(), 1, std::multiplies<size_t>());
174 }
175
176
182 size_t stride(const size_t axis) const {
183 if (axis >= A) {
184 throw std::invalid_argument("DenseVectorizer::offset(const std::array<size_t, A>&): The given axis does not exist.");
185 }
186
187 return this->strides()[axis];
188 }
189
190
194 const std::array<size_t, A>& strides() const { return this->m_strides; }
195};
196
197
198/*
199 * MARK: Convenience aliases
200 */
201
202// A trivial vectorizer that offers tuple-based indexing for 0 arguments.
204
205// A vectorizer that offers tuple-based indexing for 1 argument.
207
208// A vectorizer that offers tuple-based indexing for 2 arguments.
210
211// A vectorizer that offers tuple-based indexing for a general number of arguments.
212template <size_t A>
214
215
216} // namespace GQCP
Definition: DenseVectorizer.hpp:49
size_t numberOfElements() const
Definition: DenseVectorizer.hpp:172
const std::array< size_t, A > & dimensions() const
Definition: DenseVectorizer.hpp:159
size_t offset(const std::array< size_t, A > &indices) const
Definition: DenseVectorizer.hpp:124
size_t dimension(const size_t axis) const
Definition: DenseVectorizer.hpp:148
static constexpr auto NumberOfAxes
Definition: DenseVectorizer.hpp:162
size_t stride(const size_t axis) const
Definition: DenseVectorizer.hpp:182
DenseVectorizer(const std::array< size_t, A > &dimensions, const Ordering ordering=Ordering::ColumnMajor)
Definition: DenseVectorizer.hpp:72
size_t numberOfAxes() const
Definition: DenseVectorizer.hpp:167
DenseVectorizer()
Definition: DenseVectorizer.hpp:109
const std::array< size_t, A > & strides() const
Definition: DenseVectorizer.hpp:194
Definition: BaseOneElectronIntegralBuffer.hpp:25
Ordering
Definition: DenseVectorizer.hpp:34