TBTK
Need a break? Support the development by playing Polarity Puzzles
FockSpace.h
1 /* Copyright 2017 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
17 
25 #ifndef COM_DAFER45_TBTK_FOCK_SPACE
26 #define COM_DAFER45_TBTK_FOCK_SPACE
27 
28 #include "TBTK/BitRegister.h"
30 #include "TBTK/FockState.h"
31 #include "TBTK/FockStateMap/DefaultMap.h"
32 #include "TBTK/FockStateMap/FockStateMap.h"
33 #include "TBTK/FockStateMap/LookupTableMap.h"
34 #include "TBTK/FockStateRuleSet.h"
35 #include "TBTK/FockStateRule/FockStateRule.h"
36 #include "TBTK/FockStateRule/WrapperRule.h"
38 #include "TBTK/LadderOperator.h"
39 //#include "Model.h"
40 #include "TBTK/Statistics.h"
41 
42 namespace TBTK{
43 
44 template<typename BIT_REGISTER>
45 class FockSpace{
46 public:
48  FockSpace();
49 
51  FockSpace(
52  const HoppingAmplitudeSet *hoppingAmplitudeSet,
53  Statistics statistics,
54  unsigned int maxParticlesPerState
55  );
56 
58  FockSpace(const FockSpace &fockSpace);
59 
61  ~FockSpace();
62 
64  FockSpace& operator=(const FockSpace &rhs);
65 
67  LadderOperator<BIT_REGISTER> const* const* getOperators() const;
68 
70  FockState<BIT_REGISTER> getVacuumState() const;
71 
73  unsigned int getNumFermions(
74  const FockState<BIT_REGISTER> &fockState
75  ) const;
76 
79  unsigned int getNumParticles(
80  const FockState<BIT_REGISTER> &fockState,
81  const Index &index
82  ) const;
83 
86  unsigned int getSumParticles(
87  const FockState<BIT_REGISTER> &fockState,
88  const Index &pattern
89  ) const;
90 
92  FockStateMap::FockStateMap<BIT_REGISTER>* createFockStateMap(
93  int numParticles
94  ) const;
95 
97  FockStateMap::FockStateMap<BIT_REGISTER>* createFockStateMap(
98  const FockStateRule::FockStateRule &rule
99  ) const;
100 
102  FockStateMap::FockStateMap<BIT_REGISTER>* createFockStateMap(
103  std::initializer_list<const FockStateRule::WrapperRule> rules
104  ) const;
105 
107  FockStateMap::FockStateMap<BIT_REGISTER>* createFockStateMap(
108  std::vector<FockStateRule::WrapperRule> rules
109  ) const;
110 
112  FockStateMap::FockStateMap<BIT_REGISTER>* createFockStateMap(
113  const FockStateRuleSet &rules
114  ) const;
115 
117  const HoppingAmplitudeSet* getHoppingAmplitudeSet() const;
118 private:
120  Statistics statistics;
121 
123  unsigned int exponentialDimension;
124 
126  const HoppingAmplitudeSet *hoppingAmplitudeSet;
127 
129  FockState<BIT_REGISTER> *vacuumState;
130 
132  LadderOperator<BIT_REGISTER> **operators;
133 
135  unsigned int (*stateMapCallback)(
136  const FockState<BIT_REGISTER> &fockState
137  );
138 
141 // FockStateMap::FockStateMap<BIT_REGISTER> *fockStateMap;
142 };
143 
144 template<typename BIT_REGISTER>
145 FockSpace<BIT_REGISTER>::FockSpace(){
146  hoppingAmplitudeSet = nullptr;
147  vacuumState = nullptr;
148  operators = nullptr;
149 // fockStateMap = nullptr;
150 }
151 
152 template<typename BIT_REGISTER>
153 FockSpace<BIT_REGISTER>::FockSpace(const FockSpace &fockSpace){
154  statistics = fockSpace.statistics;
155  exponentialDimension = fockSpace.exponentialDimension;
156  hoppingAmplitudeSet = fockSpace.hoppingAmplitudeSet;
157  if(fockSpace.vacuumState == nullptr)
158  vacuumState = nullptr;
159  else
160  vacuumState = new FockState<BIT_REGISTER>(*fockSpace.vacuumState);
161  if(fockSpace.operators == nullptr){
162  operators = nullptr;
163  }
164  else{
165  operators = new LadderOperator<BIT_REGISTER>*[
166  hoppingAmplitudeSet->getBasisSize()
167  ];
168  for(
169  int n = 0;
170  n < hoppingAmplitudeSet->getBasisSize();
171  n++
172  ){
173  operators[n] = new LadderOperator<BIT_REGISTER>[2];
174  for(unsigned int c = 0; c < 2; c++)
175  operators[n][c] = fockSpace.operators[n][c];
176  }
177  }
178 }
179 
180 template<typename BIT_REGISTER>
181 FockSpace<BIT_REGISTER>::~FockSpace(){
182  if(operators != nullptr){
183  for(int n = 0; n < hoppingAmplitudeSet->getBasisSize(); n++)
184  delete [] operators[n];
185  delete [] operators;
186  }
187 }
188 
189 template<typename BIT_REGISTER>
190 FockSpace<BIT_REGISTER>& FockSpace<BIT_REGISTER>::operator=(
191  const FockSpace &rhs
192 ){
193  if(this != &rhs){
194  statistics = rhs.statistics;
195  exponentialDimension = rhs.exponentialDimension;
196  if(vacuumState != nullptr)
197  delete vacuumState;
198  if(rhs.vacuumState == nullptr){
199  vacuumState = nullptr;
200  }
201  else{
202  vacuumState
203  = new FockState<BIT_REGISTER>(*rhs.vacuumState);
204  }
205 
206  if(operators != nullptr){
207  for(
208  int n = 0;
209  n < hoppingAmplitudeSet->getBasisSize();
210  n++
211  ){
212  delete operators[n];
213  }
214  delete operators;
215  }
216  hoppingAmplitudeSet = rhs.hoppingAmplitudeSet;
217  if(rhs.operators == nullptr){
218  operators = nullptr;
219  }
220  else{
221  operators = new LadderOperator<BIT_REGISTER>*[
222  hoppingAmplitudeSet->getBasisSize()
223  ];
224  for(
225  int n = 0;
226  n < hoppingAmplitudeSet->getBasisSize();
227  n++
228  ){
229  operators[n]
230  = new LadderOperator<BIT_REGISTER>[2];
231  for(unsigned int c = 0; c < 2; c++)
232  operators[n][c] = rhs.operators[n][c];
233  }
234  }
235  }
236 
237  return *this;
238 }
239 
240 template<typename BIT_REGISTER>
241 LadderOperator<BIT_REGISTER> const* const* FockSpace<BIT_REGISTER>::getOperators(
242 ) const{
243  return operators;
244 }
245 
246 template<typename BIT_REGISTER>
247 FockState<BIT_REGISTER> FockSpace<BIT_REGISTER>::getVacuumState() const{
248  return *vacuumState;
249 }
250 
251 template<typename BIT_REGISTER>
252 unsigned int FockSpace<BIT_REGISTER>::getNumFermions(const FockState<BIT_REGISTER> &fockState) const{
253  switch(statistics){
254  case Statistics::FermiDirac:
255  return fockState.bitRegister.getNumOneBits();
256  case Statistics::BoseEinstein:
257  return 0;
258  default:
259  TBTKExit(
260  "FockSpace<BIT_REGISTER>::getNumFermions()",
261  "This should never happen.",
262  "Contact the developer."
263  );
264  }
265 }
266 
267 template<typename BIT_REGISTER>
268 unsigned int FockSpace<BIT_REGISTER>::getNumParticles(
269  const FockState<BIT_REGISTER> &fockState,
270  const Index &index
271 ) const{
272  return operators[hoppingAmplitudeSet->getBasisIndex(index)][0].getNumParticles(fockState);
273 }
274 
275 template<typename BIT_REGISTER>
276 unsigned int FockSpace<BIT_REGISTER>::getSumParticles(
277  const FockState<BIT_REGISTER> &fockState,
278  const Index &pattern
279 ) const{
280  if(pattern.isPatternIndex()){
281  std::vector<Index> indexList = hoppingAmplitudeSet->getIndexList(pattern);
282 
283  unsigned int numParticles = 0;
284  for(unsigned int n = 0; n < indexList.size(); n++){
285  numParticles += getNumParticles(
286  fockState,
287  indexList.at(n)
288  );
289  }
290 
291  return numParticles;
292  }
293  else{
294  return getNumParticles(fockState, pattern);
295  }
296 }
297 
298 template<typename BIT_REGISTER>
299 FockStateMap::FockStateMap<BIT_REGISTER>* FockSpace<BIT_REGISTER>::createFockStateMap(int numParticles) const{
300  if(numParticles < 0){
301  FockStateMap::DefaultMap<BIT_REGISTER> *fockStateMap = new FockStateMap::DefaultMap<BIT_REGISTER>(
302  exponentialDimension
303  );
304 
305  return fockStateMap;
306  }
307  else{
308  FockStateMap::LookupTableMap<BIT_REGISTER> *fockStateMap = new FockStateMap::LookupTableMap<BIT_REGISTER>(
309  exponentialDimension
310  );
311 
312  FockState<BIT_REGISTER> fockState = getVacuumState();
313  for(unsigned int n = 0; n < (unsigned int)(1 << exponentialDimension); n++){
314  if(fockState.getBitRegister().getNumOneBits() == (unsigned int)numParticles)
315  fockStateMap->addState(fockState);
316 
317  fockState.getBitRegister()++;
318  }
319 
320  return fockStateMap;
321  }
322 }
323 
324 template<typename BIT_REGISTER>
325 FockStateMap::FockStateMap<BIT_REGISTER>* FockSpace<BIT_REGISTER>::createFockStateMap(const FockStateRule::FockStateRule &rule) const{
326  FockStateRuleSet fockStateRuleSet;
327  fockStateRuleSet.addFockStateRule(rule);
328  return createFockStateMap(fockStateRuleSet);
329 }
330 
331 template<typename BIT_REGISTER>
332 FockStateMap::FockStateMap<BIT_REGISTER>* FockSpace<BIT_REGISTER>::createFockStateMap(
333  std::initializer_list<const FockStateRule::WrapperRule> rules
334 ) const{
335  FockStateRuleSet fockStateRuleSet;
336  for(unsigned int n = 0; n < rules.size(); n++)
337  fockStateRuleSet.addFockStateRule(*(rules.begin()+n));
338  return createFockStateMap(fockStateRuleSet);
339 }
340 
341 template<typename BIT_REGISTER>
342 FockStateMap::FockStateMap<BIT_REGISTER>* FockSpace<BIT_REGISTER>::createFockStateMap(
343  std::vector<FockStateRule::WrapperRule> rules
344 ) const{
345  FockStateRuleSet fockStateRuleSet;
346  for(unsigned int n = 0; n < rules.size(); n++)
347  fockStateRuleSet.addFockStateRule(rules.at(n));
348  return createFockStateMap(fockStateRuleSet);
349 }
350 
351 template<typename BIT_REGISTER>
352 FockStateMap::FockStateMap<BIT_REGISTER>* FockSpace<BIT_REGISTER>::createFockStateMap(
353  const FockStateRuleSet &rules
354 ) const{
355  FockStateMap::LookupTableMap<BIT_REGISTER> *fockStateMap = new FockStateMap::LookupTableMap<BIT_REGISTER>(
356  exponentialDimension
357  );
358 
359  if(rules.getSize() == 0){
360  FockStateMap::DefaultMap<BIT_REGISTER> *fockStateMap = new FockStateMap::DefaultMap<BIT_REGISTER>(
361  exponentialDimension
362  );
363 
364  return fockStateMap;
365  }
366  else{
367  if(exponentialDimension > 31){
368  //See comment bellow
369  TBTKExit(
370  "FockSpace::createFockStateMap()",
371  "FockSpaces with more than 31 states not yet supported using lookup table.",
372  ""
373  );
374  }
375 
376  //This loop is very slow for large exponential dimension and a
377  //better method should be implemented that can take advantage
378  //of the FockStateRules more directly.
379  FockState<BIT_REGISTER> fockState = getVacuumState();
380  for(unsigned int n = 0; n < (unsigned int)(1 << exponentialDimension); n++){
381  if(rules.isSatisfied(*this, fockState))
382  fockStateMap->addState(fockState);
383 
384  fockState.getBitRegister()++;
385  }
386  }
387 
388  return fockStateMap;
389 }
390 
391 template<typename BIT_REGISTER>
392 const HoppingAmplitudeSet* FockSpace<BIT_REGISTER>::getHoppingAmplitudeSet() const{
393  return hoppingAmplitudeSet;
394 }
395 
396 }; //End of namespace TBTK
397 
398 #endif
399 
Register of bits.
Enum class for Fermi-Dirac and Bose-Einstein statistics.
HoppingAmplitude container.
Register of bits.
Definition: Boolean.h:32
Statistics
Definition: Statistics.h:29