TBTK
Need a break? Support the development by playing Polarity Puzzles
LadderOperator.h
1 /* Copyright 2016 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 
24 #ifndef COM_DAFER45_TBTK_LADDER_OPERATOR
25 #define COM_DAFER45_TBTK_LADDER_OPERATOR
26 
27 #include "TBTK/FockState.h"
29 #include "TBTK/Statistics.h"
30 
31 namespace TBTK{
32 
33 template<typename BIT_REGISTER>
34 class LadderOperator{
35 public:
37  enum class Type {Creation, Annihilation};
38 
40  LadderOperator();
41 
43  LadderOperator(
44  Type type,
45  Statistics statistics,
46  const HoppingAmplitudeSet *hoppingAmplitudeSet,
47  unsigned int state,
48  unsigned int numBitsPerState,
49  unsigned int maxOccupation,
50  const FockState<BIT_REGISTER> &templateState,
51  const BIT_REGISTER &fermionMask
52  );
53 
55  ~LadderOperator();
56 
58  Type getType() const;
59 
61  const Index getPhysicalIndex() const;
62 
64  unsigned int getState() const;
65 
67  unsigned int getNumParticles(
68  const FockState<BIT_REGISTER> &fockState
69  ) const;
70 
72  FockState<BIT_REGISTER>& operator*(FockState<BIT_REGISTER> &rhs) const;
73 private:
75  Type type;
76 
78  Statistics statistics;
79 
81  const HoppingAmplitudeSet *hoppingAmplitudeSet;
82 
84  unsigned int state;
85 
87  BIT_REGISTER stateMask;
88 
90  BIT_REGISTER leastSignificantBit;
91 
93  unsigned int leastSignificantBitIndex;
94 
96  BIT_REGISTER maxOccupation;
97 
100  BIT_REGISTER moreSignificantFermionMask;
101 };
102 
103 template<typename BIT_REGISTER>
104 LadderOperator<BIT_REGISTER>::LadderOperator(){
105 }
106 
107 template<typename BIT_REGISTER>
108 LadderOperator<BIT_REGISTER>::LadderOperator(
109  Type type,
110  Statistics statistics,
111  const HoppingAmplitudeSet *hoppingAmplitudeSet,
112  unsigned int state,
113  unsigned int numBitsPerState,
114  unsigned int maxOccupation,
115  const FockState<BIT_REGISTER> &templateState,
116  const BIT_REGISTER &fermionMask
117 ) :
118  stateMask(templateState.bitRegister),
119  leastSignificantBit(templateState.bitRegister),
120  maxOccupation(templateState.bitRegister),
121  moreSignificantFermionMask(fermionMask)
122 {
123  this->type = type;
124  this->statistics = statistics;
125  this->hoppingAmplitudeSet = hoppingAmplitudeSet;
126  this->state = state;
127 
128  leastSignificantBitIndex = state*numBitsPerState;
129 
130  for(unsigned int n = 0; n < stateMask.getNumBits(); n++){
131  if(n >= leastSignificantBitIndex && n < leastSignificantBitIndex + numBitsPerState)
132  stateMask.setBit(n, 1);
133  else
134  stateMask.setBit(n, 0);
135 
136  if(n == leastSignificantBitIndex)
137  leastSignificantBit.setBit(n, 1);
138  else
139  leastSignificantBit.setBit(n, 0);
140  }
141 
142  this->maxOccupation = maxOccupation;
143  this->maxOccupation = (this->maxOccupation << leastSignificantBitIndex);
144 
145  for(unsigned int n = 0; n < moreSignificantFermionMask.getNumBits(); n++){
146  this->moreSignificantFermionMask.setBit(n, false);
147  if(leastSignificantBit.getBit(n))
148  break;
149  }
150 }
151 
152 template<typename BIT_REGISTER>
153 LadderOperator<BIT_REGISTER>::~LadderOperator(){
154 }
155 
156 template<typename BIT_REGISTER>
157 typename LadderOperator<BIT_REGISTER>::Type LadderOperator<BIT_REGISTER>::getType() const{
158  return type;
159 }
160 
161 template<typename BIT_REGISTER>
162 const Index LadderOperator<BIT_REGISTER>::getPhysicalIndex() const{
163  return hoppingAmplitudeSet->getPhysicalIndex(state);
164 }
165 
166 template<typename BIT_REGISTER>
167 unsigned int LadderOperator<BIT_REGISTER>::getState() const{
168  return state;
169 }
170 
171 template<typename BIT_REGISTER>
172 unsigned int LadderOperator<BIT_REGISTER>::getNumParticles(
173  const FockState<BIT_REGISTER> &fockState
174 ) const{
175  return ((fockState.getBitRegister() & stateMask) >> leastSignificantBitIndex).toUnsignedInt();
176 }
177 
178 template<typename BIT_REGISTER>
179 FockState<BIT_REGISTER>& LadderOperator<BIT_REGISTER>::operator*(
180  FockState<BIT_REGISTER> &rhs
181 ) const{
182  switch(type){
183  case Type::Creation:
184  if((rhs.bitRegister & stateMask) == maxOccupation){
185  rhs.bitRegister.setMostSignificantBit();
186  break;
187  }
188  rhs.bitRegister += leastSignificantBit;
189  break;
190  case Type::Annihilation:
191  if(!(rhs.bitRegister & stateMask).toBool()){
192  rhs.bitRegister.setMostSignificantBit();
193  break;
194  }
195  rhs.bitRegister -= leastSignificantBit;
196  break;
197  default:
198  TBTKExit(
199  "LadderOperator<BIT_REGISTER>::operator*()",
200  "This should never happen.",
201  "Contact the developer."
202  );
203  }
204 
205  switch(statistics){
206  case Statistics::FermiDirac:
207  rhs.prefactor *= pow(-1, (rhs.bitRegister & moreSignificantFermionMask).getNumOneBits());
208  break;
209  case Statistics::BoseEinstein:
210  break;
211  default:
212  TBTKExit(
213  "LadderOperator<BIT_REGISTER>::operator*()",
214  "This should never happen.",
215  "Contact the developer."
216  );
217  }
218 
219  return rhs;
220 }
221 
222 }; //End of namespace TBTK
223 
224 #endif
225 
Array< DataType > pow(const Array< DataType > &array, double exponent)
Definition: ArrayAlgorithms.h:747
Enum class for Fermi-Dirac and Bose-Einstein statistics.
HoppingAmplitude container.
Definition: Boolean.h:32
const Vector2d operator*(double lhs, const Vector2d &rhs)
Definition: Vector2d.h:129
Statistics
Definition: Statistics.h:29