LIBINT 2.9.0
quanta.h
1/*
2 * Copyright (C) 2004-2024 Edward F. Valeev
3 *
4 * This file is part of Libint compiler.
5 *
6 * Libint compiler is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Libint compiler is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Libint compiler. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef _libint2_src_bin_libint_quanta_h_
22#define _libint2_src_bin_libint_quanta_h_
23
24#include <global_macros.h>
25#include <iter.h>
26#include <smart_ptr.h>
27
28#include <cassert>
29#include <vector>
30
31namespace libint2 {
32
39 public Hashable<LIBINT2_UINT_LEAST64, ComputeKey> {
40 public:
41 typedef DummyIterator iter_type;
43 static const LIBINT2_UINT_LEAST64 max_quantum_number = 100;
44
45 virtual ~QuantumSet() {}
46 virtual std::string label() const = 0;
47
49 virtual unsigned int num_quanta() const = 0;
51 virtual void inc(unsigned int i) = 0;
53 virtual void dec(unsigned int i) = 0;
54};
55
59template <typename T, unsigned int N>
60class QuantumNumbers : public QuantumSet {
61 std::vector<T> qn_;
62
63 public:
64 typedef QuantumSet parent_type;
67
68 QuantumNumbers(const std::vector<T>& qn);
69 QuantumNumbers(const std::shared_ptr<QuantumNumbers>&);
70 QuantumNumbers(const std::shared_ptr<QuantumSet>&);
71 QuantumNumbers(const std::shared_ptr<ConstructablePolymorphically>&);
74
75 bool operator==(const QuantumNumbers&) const;
76 std::string label() const override;
77
79 void inc(unsigned int i) override { ++qn_.at(i); }
81 void dec(unsigned int i) override {
82#if CHECK_SAFETY
83 if (qn_.at(i) == T(0))
84 throw std::runtime_error(
85 "QuantumNumbers::dec -- quantum number already zero");
86#endif
87 --qn_.at(i);
88 }
89
91 const T elem(unsigned int i) const { return qn_.at(i); }
92
94 unsigned int num_quanta() const { return qn_.size(); }
95
97 LIBINT2_UINT_LEAST64 key() const override {
98 LIBINT2_UINT_LEAST64 key = 0;
99 LIBINT2_UINT_LEAST64 pfac = 1;
100 const int maxi = ((int)num_quanta()) - 1;
101 for (int i = maxi; i >= 0; i--) {
102 key += pfac * qn_[i];
104 }
105 assert(key < this->max_key());
106 return key;
107 }
108
110 LIBINT2_UINT_LEAST64 max_key() const {
111 LIBINT2_UINT_LEAST64 max_key = 1;
112 const int maxi = ((int)num_quanta()) - 1;
113 for (int i = maxi; i >= 0; i--) {
115 }
116 return max_key;
117 }
118};
119
120template <typename T, unsigned int N>
121QuantumNumbers<T, N>::QuantumNumbers(const std::vector<T>& qn) : qn_(qn) {}
122
123template <typename T, unsigned int N>
124QuantumNumbers<T, N>::QuantumNumbers(
125 const std::shared_ptr<QuantumNumbers>& sptr)
126 : qn_(sptr->qn_) {}
127
128template <typename T, unsigned int N>
129QuantumNumbers<T, N>::QuantumNumbers(const std::shared_ptr<QuantumSet>& sptr) {
130 const std::shared_ptr<QuantumNumbers<T, N> > sptr_cast =
131 std::dynamic_pointer_cast<QuantumNumbers, QuantumSet>(sptr);
132#if CHECK_SAFETY
133 if (sptr_cast == 0)
134 throw std::runtime_error(
135 "QuantumNumbers<T,N>::QuantumNumbers(const "
136 "std::shared_ptr<QuantumSet>& sptr) -- type of sptr is incompatible "
137 "with QuantumNumbers");
138#endif
139
140 qn_ = sptr_cast->qn_;
141}
142
143template <typename T, unsigned int N>
144QuantumNumbers<T, N>::QuantumNumbers(
145 const std::shared_ptr<ConstructablePolymorphically>& sptr) {
146 const std::shared_ptr<QuantumNumbers<T, N> > sptr_cast =
147 std::dynamic_pointer_cast<QuantumNumbers, ConstructablePolymorphically>(
148 sptr);
149#if CHECK_SAFETY
150 if (sptr_cast == 0)
151 throw std::runtime_error(
152 "QuantumNumbers<T,N>::QuantumNumbers(const "
153 "std::shared_ptr<ConstructablePolymorphically>& sptr) -- type of sptr "
154 "is incompatible with QuantumNumbers");
155#endif
156
157 qn_ = sptr_cast->qn_;
158}
159
160template <typename T, unsigned int N>
161QuantumNumbers<T, N>::QuantumNumbers(const ConstructablePolymorphically& sptr) {
162 const QuantumNumbers<T, N>& sptr_cast =
163 dynamic_cast<const QuantumNumbers&>(sptr);
164 qn_ = sptr_cast.qn_;
165}
166
167template <typename T, unsigned int N>
168QuantumNumbers<T, N>::~QuantumNumbers() {}
169
170template <typename T, unsigned int N>
171bool QuantumNumbers<T, N>::operator==(const QuantumNumbers& a) const {
172 return qn_ == a.qn_;
173}
174
175template <typename T, unsigned int N>
176std::string QuantumNumbers<T, N>::label() const {
177 std::ostringstream oss;
178 oss << "{";
179 if (qn_.size() > 0) oss << qn_[0];
180 for (int i = 1; i < qn_.size(); i++) oss << "," << qn_[i];
181 oss << "}";
182 return oss.str();
183}
184
185// typedef QuantumNumbers<unsigned int,0> NullQuantumSet;
186
192template <typename T, unsigned int N>
194 T qn_[N];
195
196 public:
197 typedef QuantumSet parent_type;
200
201 // Set all quanta to val
202 QuantumNumbersA(const T& val);
203 QuantumNumbersA(const T* qn);
204 QuantumNumbersA(const std::vector<T>& qn);
205 QuantumNumbersA(const std::shared_ptr<QuantumNumbersA>&);
206 QuantumNumbersA(const std::shared_ptr<QuantumSet>&);
207 QuantumNumbersA(const std::shared_ptr<ConstructablePolymorphically>&);
209
210 bool operator==(const QuantumNumbersA&) const;
211 std::string label() const override;
212
214 void inc(unsigned int i) override { ++qn_[i]; }
216 void dec(unsigned int i) override {
217#if CHECK_SAFETY
218 if (qn_[i] == T(0))
219 throw std::runtime_error(
220 "QuantumNumbersA::dec -- quantum number already zero");
221#endif
222 --qn_[i];
223 }
224
226 const T elem(unsigned int i) const { return qn_[i]; }
227
229 void set_elem(unsigned int i, const T& value) { qn_[i] = value; }
230
232 unsigned int num_quanta() const override { return N; }
233
235 LIBINT2_UINT_LEAST64 key() const override {
236 LIBINT2_UINT_LEAST64 key = 0;
237 LIBINT2_UINT_LEAST64 pfac = 1;
238 const int maxi = ((int)num_quanta()) - 1;
239 for (int i = maxi; i >= 0; i--) {
240 key += pfac * qn_[i];
242 }
243 assert(key < this->max_key());
244 return key;
245 }
246
248 LIBINT2_UINT_LEAST64 max_key() const {
249 LIBINT2_UINT_LEAST64 max_key = 1;
250 const int maxi = ((int)num_quanta()) - 1;
251 for (int i = maxi; i >= 0; i--) {
253 }
254 return max_key;
255 }
256};
257
258template <typename T, unsigned int N>
259QuantumNumbersA<T, N>::QuantumNumbersA(const T& val) {
260 for (unsigned int i = 0; i < N; i++) qn_[i] = val;
261}
262
263template <typename T, unsigned int N>
264QuantumNumbersA<T, N>::QuantumNumbersA(const T* qn) {
265 for (int i = 0; i < N; i++) qn_[i] = qn[i];
266}
267
268template <typename T, unsigned int N>
269QuantumNumbersA<T, N>::QuantumNumbersA(const std::vector<T>& qn) {
270 for (int i = 0; i < N; i++) qn_[i] = qn[i];
271}
272
273template <typename T, unsigned int N>
274QuantumNumbersA<T, N>::QuantumNumbersA(
275 const std::shared_ptr<QuantumNumbersA>& sptr) {
276 T* qn = sptr->qn_;
277 for (unsigned int i = 0; i < N; i++) qn_[i] = qn[i];
278}
279
280template <typename T, unsigned int N>
281QuantumNumbersA<T, N>::QuantumNumbersA(
282 const std::shared_ptr<QuantumSet>& sptr) {
283 const std::shared_ptr<QuantumNumbersA<T, N> > sptr_cast =
284 std::dynamic_pointer_cast<QuantumNumbersA, QuantumSet>(sptr);
285#if CHECK_SAFETY
286 if (sptr_cast == 0)
287 throw std::runtime_error(
288 "QuantumNumbersA<T,N>::QuantumNumbersA(const "
289 "std::shared_ptr<QuantumSet>& sptr) -- type of sptr is incompatible "
290 "with QuantumNumbersA");
291#endif
292
293 T* qn = sptr_cast->qn_;
294 for (int i = 0; i < N; i++) qn_[i] = qn[i];
295}
296
297template <typename T, unsigned int N>
298QuantumNumbersA<T, N>::QuantumNumbersA(
299 const std::shared_ptr<ConstructablePolymorphically>& sptr) {
300 const std::shared_ptr<QuantumNumbersA<T, N> > sptr_cast =
301 std::dynamic_pointer_cast<QuantumNumbersA, ConstructablePolymorphically>(
302 sptr);
303#if CHECK_SAFETY
304 if (sptr_cast == 0)
305 throw std::runtime_error(
306 "QuantumNumbersA<T,N>::QuantumNumbersA(const "
307 "std::shared_ptr<ConstructablePolymorphically>& sptr) -- type of sptr "
308 "is incompatible with QuantumNumbersA");
309#endif
310 T* qn = sptr_cast->qn_;
311 for (int i = 0; i < N; i++) qn_[i] = qn[i];
312}
313
314template <typename T, unsigned int N>
315QuantumNumbersA<T, N>::~QuantumNumbersA() {}
316
317template <typename T, unsigned int N>
318bool QuantumNumbersA<T, N>::operator==(const QuantumNumbersA& a) const {
319 const T* qn0 = qn_;
320 const T* qn1 = a.qn_;
321 for (int i = 0; i < N; i++, ++qn0, ++qn1)
322 if (*qn0 != *qn1) return false;
323
324 return true;
325}
326
327template <typename T, unsigned int N>
328std::string QuantumNumbersA<T, N>::label() const {
329 std::ostringstream oss;
330 oss << "{";
331 if (N > 0) oss << qn_[0];
332 for (unsigned int i = 1; i < N; i++) oss << "," << qn_[i];
333 oss << "}";
334 return oss.str();
335}
336
338template <typename T>
339class QuantumNumbersA<T, 0> : public QuantumSet {
340 public:
341 typedef QuantumSet parent_type;
344
345 QuantumNumbersA() {}
346 QuantumNumbersA(const T* qn) {}
347 QuantumNumbersA(const std::vector<T>& qn) {}
348 QuantumNumbersA(const std::shared_ptr<QuantumNumbersA>&) {}
349 QuantumNumbersA(const std::shared_ptr<QuantumSet>&) {}
350 QuantumNumbersA(const std::shared_ptr<ConstructablePolymorphically>&) {}
351 ~QuantumNumbersA() {}
352
353 bool operator==(const QuantumNumbersA&) const { return true; }
354 std::string label() const override { return "{}"; }
355
357 void inc(unsigned int i) override {
358 throw std::runtime_error(
359 "QuantumNumbersA<T,0>::inc -- no quantum numbers to increment");
360 }
362 void dec(unsigned int i) override {
363 throw std::runtime_error(
364 "QuantumNumbersA<T,0>::inc -- no quantum numbers to decrement");
365 }
367 const T elem(unsigned int i) const {
368 throw std::runtime_error(
369 "QuantumNumbersA<T,0>::inc -- no quantum numbers to return");
370 }
372 unsigned int num_quanta() const override { return 0; }
373
375 LIBINT2_UINT_LEAST64 key() const override { return 0; }
376
378 LIBINT2_UINT_LEAST64 max_key() const { return 1; }
379};
380
382template <typename T, unsigned int N>
396
397}; // namespace libint2
398
399#endif
ConstructablePolymorphically is a base for all objects which can be constructed using a std::shared_p...
Definition polyconstr.h:30
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition hashable.h:79
unsigned int num_quanta() const override
Implementation of QuantumSet::num_quanta()
Definition quanta.h:372
void dec(unsigned int i) override
Decrement quantum number i.
Definition quanta.h:362
void inc(unsigned int i) override
Increment quantum number i.
Definition quanta.h:357
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition quanta.h:378
QuantumNumbersA iter_type
QuantumSet is a set of one QuantumSet.
Definition quanta.h:343
const T elem(unsigned int i) const
Return i-th quantum number.
Definition quanta.h:367
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable::key()
Definition quanta.h:375
QuantumNumbersA<T,N> is a set of N quantum numbers of type T implemented in terms of a C-style array.
Definition quanta.h:193
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable::key()
Definition quanta.h:235
void dec(unsigned int i) override
Decrement quantum number i.
Definition quanta.h:216
QuantumNumbersA iter_type
QuantumSet is a set of one QuantumSet.
Definition quanta.h:199
const T elem(unsigned int i) const
Return i-th quantum number.
Definition quanta.h:226
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition quanta.h:248
void inc(unsigned int i) override
Increment quantum number i.
Definition quanta.h:214
void set_elem(unsigned int i, const T &value)
Return i-th quantum number.
Definition quanta.h:229
unsigned int num_quanta() const override
Implementation of QuantumSet::num_quanta()
Definition quanta.h:232
QuantumNumbers<T,N> is a set of N quantum numbers of type T implemented in terms of std::vector.
Definition quanta.h:60
unsigned int num_quanta() const
Return i-th quantum number.
Definition quanta.h:94
void inc(unsigned int i) override
Increment quantum number i.
Definition quanta.h:79
void dec(unsigned int i) override
Decrement quantum number i.
Definition quanta.h:81
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition quanta.h:110
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable::key()
Definition quanta.h:97
QuantumNumbers iter_type
QuantumSet is a set of one QuantumSet.
Definition quanta.h:66
const T elem(unsigned int i) const
Return i-th quantum number.
Definition quanta.h:91
QuantumSet is the base class for all (sets of) quantum numbers.
Definition quanta.h:39
virtual unsigned int num_quanta() const =0
Number of quantum numbers in the set.
virtual void dec(unsigned int i)=0
Decrement i-th quantum number.
static const LIBINT2_UINT_LEAST64 max_quantum_number
Quantum numbers lie in range [0,max_quantum_number)
Definition quanta.h:43
virtual void inc(unsigned int i)=0
Increment i-th quantum number.
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
DefaultQuantumNumbers< unsignedint, 1 >::Result mType
mType is the type that describes the auxiliary index of standard 2-body repulsion integrals
Definition quanta.h:395
DefaultQuantumNumbers< int, 0 >::Result EmptySet
EmptySet is the type that describes null set of auxiliary indices.
Definition quanta.h:390
Default implementation of QuantumNumbers.
Definition quanta.h:383
QuantumNumbersA< T, N > Result
This defines which QuantumNumbers implementation to use.
Definition quanta.h:385