• Keine Ergebnisse gefunden

A.2. Encoding, manipulating, and creating product basis states of the

A.2.1. Encoding and manipulating product basis states

A product basis state

ψ {ai},{n}

can be stored in the form of asingleinteger variableI by using the individual bits of the integer for encoding the information about the magnon numbers {ai} and the occupation numbers {n}. Such an approach is advantageous for a number of reasons:

1. It leads to a low memory consumption of the product basis (which, however, might be insignificant compared to the total memory requirements of the numerical code anyway).

2. Product basis states can be manipulated using fast bitwise operations. In particular, the sign resulting from the application of a fermionic operator can be efficiently calculated.

3. Using the same integer variables, different blocks of bits storing different kind of information (such as information about the state of the spins or the fermions) can be treated independently.

4. A comparison of two product basis states simply corresponds to the compar-ison of two integer variables.

5. In particular, mapping states to integers thus automatically defines an order of the states.

In order to prevent any problems with the sign bit, the integers that are used for storing the basis states should be taken asunsigned.

The mapping to integer variables is particularly useful for fermionic systems and for spins withsi= 1/2 since a single bit is sufficient to represent an occupa-tion number n or a magnon number ai with two possible values, respectively.

Furthermore, changing the state of a particular lattice site or spin then simply corresponds to flipping a single bit of the respective integer I. In contrast, for si>1/2, more than one bit is necessary in order to represent the magnon number ai. This means that the respective part ofI has to be divided into suitable blocks of bits.

An unsigned integerI can be partitioned in the following way in order to store the information about a product basis state

ψ {ai},{n}

(see Ref. [Jaf08] for a discussion of the fermionic componentsI andI):

I ≡h

Is

| {z }

state of the localized spins

(Bsbits)

I

| {z }

state of the spin-down fermions

(Lbits)

I

| {z }

state of the spin-up fermions

(Lbits)

i

. (A.15)

This division ofIleads to the following relations (% denotes the modulo operator):

I =I+ 2LI+ 22LIs, Is=I/22L,

I= I/2L

% 2L, I=I% 2L.

(A.16)

The required constants can be obtained using, e.g., the bitwise left-shift operator : 2j= 1j. We need to be able to delete the contents of the different blocks:

Delete block Is: I =I% 22L , Delete block I: I =I&∼

2L 2L−1 , Delete block I: I =I&∼ 2L−1

.

(A.17)

Here, & is the bitwise AND operator and ∼is the bitwise NOT operator which inverts the bit pattern of the integer that it is applied to. Once a block has been erased, new information can be encoded. For example, if we want to replaceIsby Is0, we first deleteIs and then use: I =I+ 22LIs0. Access to the different blocks would be much easier if the blocks were aligned on byte-boundaries. This is an option that should be considered.

Encoding information in the fermionic components I andI

(cf. Ref. [Jaf08])

Since the occupation numbersn for lattice sitej and spin projectionσcan only take the values 0 or 1,Lbits of the integerIσ are necessary in order to represent theLlattice sites:

Iσ

nL−1σ nL−2σ nL−3σ . . . n n n .

L-1 L-2 L-3 2 1 0 j=

(A.18) Individual bits of Iσ (corresponding to single lattice sites) can be manipulated using the bitwise operators OR (|), AND (&), and XOR ():

Set bitjinIσ: Iσ=Iσ| 2j , Delete bitjinIσ: Iσ=Iσ&∼2j , Flip bitjinIσ: Iσ=Iσ 2j .

(A.19)

Furthermore, the value of bitj(i.e., the occupation numbern) can be extracted from the integerIσ in the following way:

n = Iσ/2j

& 1. (A.20)

In order to calculate, e.g., a matrix representation of the Hamiltonian, we need to know how to apply creation and destruction operators to a product basis state (compare the partition (A.15) ofI):

c

j↓| I i ∼= Sj↓(1−nj↓)

I=I2j+L ,

c

j↑| I i ∼= Sj↑(1−nj↑)

I=I2j ,

cj↓| I i ∼= Sj↓nj↓

I=I2j+L ,

cj↑| I i ∼= Sj↑nj↑

I=I2j .

(A.21)

S is the total sign that results from all fermionic anticommutations which are necessary, according to Eq. (A.13), to establish the correct order of creation operators or to “remove” the applied destruction operator, respectively. Note that the above equations (A.21) are, strictly speaking, not exact because, in a numerical implementation,I = 0 corresponds to a valid state (namely, the state without particles and magnons). From a technical point of view, Eqs. (A.21) show that for the same indicesj andσ the application of a creation and a destruction operator is very similar since in both cases the same signShas to be determined

(provided that applying the operator results in a valid state) and the same bit is flipped in the integerI.

Let us now turn to the calculation of the signsS. On the one hand, an operator acting on lattice sitej withσ= +1/2 has to be moved past all spin-up creation operators with indiceskj−1 in order to be put at the correct position according to Eq. (A.13). On the other hand, to establish the correct order, an operator withσ=−1/2 and indexj has to be moved pastall spin-up creation operators and, in addition, past all spin-down creation operators with lattice site index kj−1. Since each exchange of fermionic operators causesS (being initialized to 1) to be multiplied by −1, the sign can be efficiently calculated using the following algorithm (expressed via C/C++ pseudocode), which effectively counts the number of bits that are set in the relevant part of the respective integerI (see p. 70 of Ref. [Ouc06]):

unsigned int I, j, L;

... int sign;

unsigned int IMasked = (

I % (1j); // for spin-up I % (1(j+L)); // for spin-down for(sign = 1; IMasked; sign *= –1)

IMasked &= (IMasked – 1);

Depending on the spin projectionσand the lattice site indexj, a certain number of the high-order bits of the integerIis removed, resulting in the “masked” integer IMasked. Thefor-loop then effectively counts the bits that are set in IMasked (by deleting one set bit in each step), multiplying sign by −1 for each set bit that is encountered. Note that for non-vanishing matrix elements of the type I

c

j↓c

k↓

I0

the contributions to the signs Sj↓ and Sk↓ due to the spin-up creation operators in| I iand| I0icancel and can therefore be neglected (cf. Ref.

[Jaf08]).

Encoding information in the spin componentIs (cf. Ref. [RRSR01])

The spin component Is of the integerI has to be further divided into blocks of suitable lengths in which the information about the state of the different spins can be encoded (see Ref. [RRSR01] and also compare Refs. [Lin90, San10, Läu11]).

To this end, we need to know how many bitsBi are necessary for spin iin order to allow for the representation of all possible values of the magnon numberai:

Bi= ceiling

ln(amaxi + 1) ln 2

. (A.22)

The total number of required bits is thusBs=PNs−1

i=0 Bi. Thestart bits {bi} = {b0, b1, b2, . . . , bNs−1}of the different blocks directly result from Eq. (A.22),

b0≡0, bi=

i−1

X

j=0

Bj for i≥1, (A.23)

and lead to the following partition of the integerIs:

Is

aNs−1 . . . a2 a1 a0

.

↑ ↑ ↑ ↑ ↑ ↑

Bs bNs−1 b3 b2 b1 b0≡0

(A.24)

Without any protection against performing an illegal operation that would vio-late the boundaries of the blocks, a magnon numberai can be easily changed:

Increase aiby 1 : Is=Is+ 2bi ,

Decreaseaiby 1 : Is=Is−2bi . (A.25) Furthermore, the value ofai can be extracted and deleted (i.e., set to zero) in the following way:

Extractai: ai = Is% 2bi+1

/2bi , Delete ai: Is=Is&∼

2bi 2Bi−1

. (A.26)

After a magnon numberai has been erased, a new valuea0i can be stored in the integerIs by using: Is=Is+ 2bia0i.