LIBINT  2.1.0-stable
quanta.h
1 /*
2  * This file is a part of Libint.
3  * Copyright (C) 2004-2014 Edward F. Valeev
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program 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 General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see http://www.gnu.org/licenses/.
17  *
18  */
19 
20 #ifndef _libint2_src_bin_libint_quanta_h_
21 #define _libint2_src_bin_libint_quanta_h_
22 
23 #include <vector>
24 #include <smart_ptr.h>
25 #include <global_macros.h>
26 #include <iter.h>
27 
28 using namespace std;
29 
30 
31 namespace libint2 {
32 
38  public Hashable<LIBINT2_UINT_LEAST64,ComputeKey> {
39  public:
40  typedef DummyIterator iter_type;
42  static const LIBINT2_UINT_LEAST64 max_quantum_number = 100;
43 
44  virtual ~QuantumSet() {}
45  virtual const std::string label() const =0;
46 
48  virtual unsigned int num_quanta() const =0;
50  virtual void inc(unsigned int i) =0;
52  virtual void dec(unsigned int i) =0;
53  };
54 
57  template<typename T, unsigned int N> class QuantumNumbers : public QuantumSet {
58 
59  vector<T> qn_;
60 
61  public:
62  typedef QuantumSet parent_type;
65 
66  QuantumNumbers(const vector<T>& qn);
67  QuantumNumbers(const SafePtr<QuantumNumbers>&);
68  QuantumNumbers(const SafePtr<QuantumSet>&);
69  QuantumNumbers(const SafePtr<ConstructablePolymorphically>&);
71  ~QuantumNumbers();
72 
73  bool operator==(const QuantumNumbers&) const;
74  const std::string label() const;
75 
77  void inc(unsigned int i) { ++qn_.at(i); }
79  void dec(unsigned int i) {
80 #if CHECK_SAFETY
81  if (qn_.at(i) == T(0))
82  throw std::runtime_error("QuantumNumbers::dec -- quantum number already zero");
83 #endif
84  --qn_.at(i);
85  }
86 
88  const T elem(unsigned int i) const {
89  return qn_.at(i);
90  }
91 
93  unsigned int num_quanta() const {
94  return qn_.size();
95  }
96 
98  LIBINT2_UINT_LEAST64 key() const {
99  LIBINT2_UINT_LEAST64 key = 0;
100  LIBINT2_UINT_LEAST64 pfac = 1;
101  const int maxi = ((int)num_quanta()) - 1;
102  for(int i=maxi; i>=0; i--) {
103  key += pfac*qn_[i];
104  pfac *= QuantumSet::max_quantum_number;
105  }
106  assert(key < this->max_key());
107  return key;
108  }
109 
111  LIBINT2_UINT_LEAST64 max_key() const {
112  LIBINT2_UINT_LEAST64 max_key = 1;
113  const int maxi = ((int)num_quanta()) - 1;
114  for(int i=maxi; i>=0; i--) {
115  max_key *= QuantumSet::max_quantum_number;
116  }
117  return max_key;
118  }
119 
120  };
121 
122  template<typename T, unsigned int N>
123  QuantumNumbers<T,N>::QuantumNumbers(const vector<T>& qn) :
124  qn_(qn)
125  {
126  }
127 
128  template<typename T, unsigned int N>
129  QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<QuantumNumbers>& sptr) :
130  qn_(sptr->qn_)
131  {
132  }
133 
134  template<typename T, unsigned int N>
135  QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<QuantumSet>& sptr)
136  {
137  const SafePtr< QuantumNumbers<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbers,QuantumSet>(sptr);
138 #if CHECK_SAFETY
139  if (sptr_cast == 0)
140  throw std::runtime_error("QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<QuantumSet>& sptr) -- type of sptr is incompatible with QuantumNumbers");
141 #endif
142 
143  qn_ = sptr_cast->qn_;
144  }
145 
146  template<typename T, unsigned int N>
147  QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<ConstructablePolymorphically>& sptr)
148  {
149  const SafePtr< QuantumNumbers<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbers,ConstructablePolymorphically>(sptr);
150 #if CHECK_SAFETY
151  if (sptr_cast == 0)
152  throw std::runtime_error("QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<ConstructablePolymorphically>& sptr) -- type of sptr is incompatible with QuantumNumbers");
153 #endif
154 
155  qn_ = sptr_cast->qn_;
156  }
157 
158  template<typename T, unsigned int N>
159  QuantumNumbers<T,N>::QuantumNumbers(const ConstructablePolymorphically& sptr)
160  {
161  const QuantumNumbers<T,N>& sptr_cast = dynamic_cast<const QuantumNumbers&>(sptr);
162  qn_ = sptr_cast.qn_;
163  }
164 
165  template<typename T, unsigned int N>
167  {
168  }
169 
170  template<typename T, unsigned int N>
171  bool
173  {
174  return qn_ == a.qn_;
175  }
176 
177  template<typename T, unsigned int N>
178  const std::string
180  {
181  std::ostringstream oss;
182  oss << "{";
183  if (qn_.size() > 0)
184  oss << qn_[0];
185  for(int i=1; i<qn_.size(); i++)
186  oss << "," << qn_[i];
187  oss << "}";
188  return oss.str();
189  }
190 
191  //typedef QuantumNumbers<unsigned int,0> NullQuantumSet;
192 
193 
198  template<typename T, unsigned int N> class QuantumNumbersA : public QuantumSet {
199 
200  T qn_[N];
201 
202  public:
203  typedef QuantumSet parent_type;
206 
207  // Set all quanta to val
208  QuantumNumbersA(const T& val);
209  QuantumNumbersA(const T* qn);
210  QuantumNumbersA(const vector<T>& qn);
211  QuantumNumbersA(const SafePtr<QuantumNumbersA>&);
212  QuantumNumbersA(const SafePtr<QuantumSet>&);
213  QuantumNumbersA(const SafePtr<ConstructablePolymorphically>&);
214  ~QuantumNumbersA();
215 
216  bool operator==(const QuantumNumbersA&) const;
217  const std::string label() const;
218 
220  void inc(unsigned int i) { ++qn_[i]; }
222  void dec(unsigned int i) {
223 #if CHECK_SAFETY
224  if (qn_[i] == T(0))
225  throw std::runtime_error("QuantumNumbersA::dec -- quantum number already zero");
226 #endif
227  --qn_[i];
228  }
229 
231  const T elem(unsigned int i) const {
232  return qn_[i];
233  }
234 
236  void set_elem(unsigned int i, const T& value) {
237  qn_[i] = value;
238  }
239 
241  unsigned int num_quanta() const {
242  return N;
243  }
244 
246  LIBINT2_UINT_LEAST64 key() const {
247  LIBINT2_UINT_LEAST64 key = 0;
248  LIBINT2_UINT_LEAST64 pfac = 1;
249  const int maxi = ((int)num_quanta()) - 1;
250  for(int i=maxi; i>=0; i--) {
251  key += pfac*qn_[i];
252  pfac *= QuantumSet::max_quantum_number;
253  }
254  assert(key < this->max_key());
255  return key;
256  }
257 
259  LIBINT2_UINT_LEAST64 max_key() const {
260  LIBINT2_UINT_LEAST64 max_key = 1;
261  const int maxi = ((int)num_quanta()) - 1;
262  for(int i=maxi; i>=0; i--) {
263  max_key *= QuantumSet::max_quantum_number;
264  }
265  return max_key;
266  }
267 
268  };
269 
270  template<typename T, unsigned int N>
272  {
273  for(unsigned int i=0; i<N; i++)
274  qn_[i] = val;
275  }
276 
277  template<typename T, unsigned int N>
279  {
280  for(int i=0; i<N; i++)
281  qn_[i] = qn[i];
282  }
283 
284  template<typename T, unsigned int N>
285  QuantumNumbersA<T,N>::QuantumNumbersA(const vector<T>& qn)
286  {
287  for(int i=0; i<N; i++)
288  qn_[i] = qn[i];
289  }
290 
291  template<typename T, unsigned int N>
292  QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<QuantumNumbersA>& sptr)
293  {
294  T* qn = sptr->qn_;
295  for(unsigned int i=0; i<N; i++)
296  qn_[i] = qn[i];
297  }
298 
299  template<typename T, unsigned int N>
300  QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<QuantumSet>& sptr)
301  {
302  const SafePtr< QuantumNumbersA<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbersA,QuantumSet>(sptr);
303 #if CHECK_SAFETY
304  if (sptr_cast == 0)
305  throw std::runtime_error("QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<QuantumSet>& sptr) -- type of sptr is incompatible with QuantumNumbersA");
306 #endif
307 
308  T* qn = sptr_cast->qn_;
309  for(int i=0; i<N; i++)
310  qn_[i] = qn[i];
311  }
312 
313  template<typename T, unsigned int N>
314  QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<ConstructablePolymorphically>& sptr)
315  {
316  const SafePtr< QuantumNumbersA<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbersA,ConstructablePolymorphically>(sptr);
317 #if CHECK_SAFETY
318  if (sptr_cast == 0)
319  throw std::runtime_error("QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<ConstructablePolymorphically>& sptr) -- type of sptr is incompatible with QuantumNumbersA");
320 #endif
321  T* qn = sptr_cast->qn_;
322  for(int i=0; i<N; i++)
323  qn_[i] = qn[i];
324  }
325 
326  template<typename T, unsigned int N>
328  {
329  }
330 
331  template<typename T, unsigned int N>
332  bool
334  {
335  const T* qn0 = qn_;
336  const T* qn1 = a.qn_;
337  for(int i=0; i<N; i++, ++qn0, ++qn1)
338  if (*qn0 != *qn1)
339  return false;
340 
341  return true;
342  }
343 
344  template<typename T, unsigned int N>
345  const std::string
347  {
348  std::ostringstream oss;
349  oss << "{";
350  if (N > 0)
351  oss << qn_[0];
352  for(unsigned int i=1; i<N; i++)
353  oss << "," << qn_[i];
354  oss << "}";
355  return oss.str();
356  }
357 
359  template<typename T> class QuantumNumbersA<T,0> : public QuantumSet {
360 
361  public:
362  typedef QuantumSet parent_type;
365 
366  QuantumNumbersA() {}
367  QuantumNumbersA(const T* qn) {}
368  QuantumNumbersA(const vector<T>& qn) {}
369  QuantumNumbersA(const SafePtr<QuantumNumbersA>&) {}
370  QuantumNumbersA(const SafePtr<QuantumSet>&) {}
371  QuantumNumbersA(const SafePtr<ConstructablePolymorphically>&) {}
372  ~QuantumNumbersA() {}
373 
374  bool operator==(const QuantumNumbersA&) const { return true; }
375  const std::string label() const { return "{}"; }
376 
378  void inc(unsigned int i) { throw std::runtime_error("QuantumNumbersA<T,0>::inc -- no quantum numbers to increment"); }
380  void dec(unsigned int i) {
381  throw std::runtime_error("QuantumNumbersA<T,0>::inc -- no quantum numbers to decrement");
382  }
384  const T elem(unsigned int i) const { throw std::runtime_error("QuantumNumbersA<T,0>::inc -- no quantum numbers to return"); }
386  unsigned int num_quanta() const { return 0; }
387 
389  LIBINT2_UINT_LEAST64 key() const { return 0; }
390 
392  LIBINT2_UINT_LEAST64 max_key() const { return 1; }
393 
394  };
395 
397  template <typename T, unsigned int N>
401  };
410 
411 };
412 
413 #endif
unsigned int num_quanta() const
Implementation of QuantumSet::num_quanta()
Definition: quanta.h:386
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition: quanta.h:259
LIBINT2_UINT_LEAST64 key() const
Implements Hashable::key()
Definition: quanta.h:389
QuantumNumbersA iter_type
QuantumSet is a set of one QuantumSet.
Definition: quanta.h:364
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:30
QuantumSet is the base class for all (sets of) quantum numbers.
Definition: quanta.h:37
void dec(unsigned int i)
Decrement quantum number i.
Definition: quanta.h:79
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType...
Definition: hashable.h:72
Definition: stdarray.h:18
QuantumNumbers<T,N> is a set of N quantum numbers of type T implemented in terms of std::vector...
Definition: quanta.h:57
void dec(unsigned int i)
Decrement quantum number i.
Definition: quanta.h:380
LIBINT2_UINT_LEAST64 key() const
Implements Hashable::key()
Definition: quanta.h:98
void inc(unsigned int i)
Increment quantum number i.
Definition: quanta.h:378
QuantumNumbersA<T,N> is a set of N quantum numbers of type T implemented in terms of a C-style array...
Definition: quanta.h:198
void set_elem(unsigned int i, const T &value)
Return i-th quantum number.
Definition: quanta.h:236
void inc(unsigned int i)
Increment quantum number i.
Definition: quanta.h:77
LIBINT2_UINT_LEAST64 key() const
Implements Hashable::key()
Definition: quanta.h:246
const T elem(unsigned int i) const
Return i-th quantum number.
Definition: quanta.h:88
unsigned int num_quanta() const
Return i-th quantum number.
Definition: quanta.h:93
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition: quanta.h:111
QuantumNumbers iter_type
QuantumSet is a set of one QuantumSet.
Definition: quanta.h:64
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition: quanta.h:392
const T elem(unsigned int i) const
Return i-th quantum number.
Definition: quanta.h:231
unsigned int num_quanta() const
Implementation of QuantumSet::num_quanta()
Definition: quanta.h:241
void inc(unsigned int i)
Increment quantum number i.
Definition: quanta.h:220
void dec(unsigned int i)
Decrement quantum number i.
Definition: quanta.h:222
Default implementation of QuantumNumbers.
Definition: quanta.h:398
QuantumNumbersA iter_type
QuantumSet is a set of one QuantumSet.
Definition: quanta.h:205
const T elem(unsigned int i) const
Return i-th quantum number.
Definition: quanta.h:384
QuantumNumbersA< T, N > Result
This defines which QuantumNumbers implementation to use.
Definition: quanta.h:400