Operators as matrices
In the first example we show a small script written in Quanty that works and does not require further programming. The script creates the spin, angular momentum and Coulomb operator as matrices on a many body basis. The file conf.in defines the angular momentum of the shell and the number of electrons in this shell. We recommend to understand the quantum mechanics presented in this script, i.e. why are there 15 states for two electrons in the $p$ shell, but not to look into the script too much. You can come back to this after example 5.
The configuration file is:
- config.in
-- Angular momentum of the shell (0=="s" 1=="p" 2=="d" 3=="f") l = 1 -- Number of electrons Nelec = 1
The output is:
- Operators_as_Matrices.out
============================================================= --> This small program will print out the possible many-body states for a given electronic configuration --> The obtained states of single Slater determinants will be used as a Hilbert space for several operators. ============================================================= Calculating all possible Slater determinants for a shell with angular momentum 1 and a filling of 1 electrons ======================== O U T P U T ======================== A shell with l= 1 and a filling of 1 electrons has Binomial(6 1) = 6 possible single Slater determinants --> List of possible single Slater determinants which span the basis for all many body states: 1 |100000> 2 |010000> 3 |001000> 4 |000100> 5 |000010> 6 |000001> ============================================================= The Sz operator on a basis Single slater determinants for a shell with l = 1 and a filling of 1 electrons is: 1 |100000> -0.50 0.00 0.00 0.00 0.00 0.00 2 |010000> 0.00 0.50 0.00 0.00 0.00 0.00 3 |001000> 0.00 0.00 -0.50 0.00 0.00 0.00 4 |000100> 0.00 0.00 0.00 0.50 0.00 0.00 5 |000010> 0.00 0.00 0.00 0.00 -0.50 0.00 6 |000001> 0.00 0.00 0.00 0.00 0.00 0.50 ============================================================= The Lz operator on a basis Single slater determinants for a shell with l = 1 and a filling of 1 electrons is: 1 |100000> -1.00 0.00 0.00 0.00 0.00 0.00 2 |010000> 0.00 -1.00 0.00 0.00 0.00 0.00 3 |001000> 0.00 0.00 0.00 0.00 0.00 0.00 4 |000100> 0.00 0.00 0.00 0.00 0.00 0.00 5 |000010> 0.00 0.00 0.00 0.00 1.00 0.00 6 |000001> 0.00 0.00 0.00 0.00 0.00 1.00 ============================================================= The S^2 operator on a basis Single slater determinants for a shell with l = 1 and a filling of 1 electrons is: 1 |100000> 0.75 0.00 0.00 0.00 0.00 0.00 2 |010000> 0.00 0.75 0.00 0.00 0.00 0.00 3 |001000> 0.00 0.00 0.75 0.00 0.00 0.00 4 |000100> 0.00 0.00 0.00 0.75 0.00 0.00 5 |000010> 0.00 0.00 0.00 0.00 0.75 0.00 6 |000001> 0.00 0.00 0.00 0.00 0.00 0.75 ============================================================= The L^2 operator on a basis Single slater determinants for a shell with l = 1 and a filling of 1 electrons is: 1 |100000> 2.00 0.00 0.00 0.00 0.00 0.00 2 |010000> 0.00 2.00 0.00 0.00 0.00 0.00 3 |001000> 0.00 0.00 2.00 0.00 0.00 0.00 4 |000100> 0.00 0.00 0.00 2.00 0.00 0.00 5 |000010> 0.00 0.00 0.00 0.00 2.00 0.00 6 |000001> 0.00 0.00 0.00 0.00 0.00 2.00 ============================================================= The Coulomb operator for a shell with l = 1 is given by 2 different operators depending on the angular momentum of the expansion of 1/|r1-r2| in spherical Harmonics ============================================================= F[0] 1 |100000> 0.00 0.00 0.00 0.00 0.00 0.00 2 |010000> 0.00 0.00 0.00 0.00 0.00 0.00 3 |001000> 0.00 0.00 0.00 0.00 0.00 0.00 4 |000100> 0.00 0.00 0.00 0.00 0.00 0.00 5 |000010> 0.00 0.00 0.00 0.00 0.00 0.00 6 |000001> 0.00 0.00 0.00 0.00 0.00 0.00 ============================================================= F[2] 1 |100000> 0.00 0.00 0.00 0.00 0.00 0.00 2 |010000> 0.00 0.00 0.00 0.00 0.00 0.00 3 |001000> 0.00 0.00 0.00 0.00 0.00 0.00 4 |000100> 0.00 0.00 0.00 0.00 0.00 0.00 5 |000010> 0.00 0.00 0.00 0.00 0.00 0.00 6 |000001> 0.00 0.00 0.00 0.00 0.00 0.00 ============================================================= Timing results Total_time | NumberOfRuns | Running | Name 0:00:00 | 1 | 0 | Create Determinants 0:00:00 | 1 | 0 | Create operators in second quantization 0:00:00 | 1 | 0 | Create operators in matrix form
For completeness, the actual code is:
- Operators_as_Matrices.Quanty
-- script contributed by Yaroslav Kvashnin. -- In order to simplify the program later on we first define some -- functions. -- Function which swaps two character in a string. It will be used -- to check all possible particles permutations. ------------------------------------------------ function swap_char(pos1, pos2, str) r=tostring((tonumber(str:sub(pos1,pos1))+3) % 2) z=tostring((tonumber(str:sub(pos2,pos2))+3) % 2) if (r ~= z) then return str:sub(1, pos1-1) .. r .. str:sub(pos1+1,pos2-1) .. z .. str:sub(pos2+1) else return str end end ------------------------------------------------ -- begin of program print("") print("=============================================================") print("--> This small program will print out the possible many-body states for a given electronic configuration"); print("--> The obtained states of single Slater determinants will be used as a Hilbert space for several operators.") print("") print("=============================================================") print("") -- read in the input dofile("conf.in") print("Calculating all possible Slater determinants for a shell with angular momentum "..l.." and a filling of "..Nelec.." electrons") -- Create the basis for quanty, define spin-orbitals and relate them -- to atomic shells. There are 4*l+2 spin-orbitals in a shell with -- angular momentum l. We label the spin-orbitals in the order from -- ml=-l to ml=l alternating down and up. Nf=4*l+2 IndexDn={} IndexUp={} j=1 for i=0,Nf-1,2 do IndexDn[j]=i IndexUp[j]=i+1 j=j+1 end -- number of bosons Nb=0 print("") print("======================== O U T P U T ========================") print("") -- Number of many particle states. Nstates=math.Binomial(Nf,Nelec) print("A shell with l= "..l.." and a filling of "..Nelec.." electrons has Binomial("..Nf.." "..Nelec..") = "..Nstates.." possible single Slater determinants") if(Nstates>3500) then print("If you want to calculate more than 3500 states you have to remove this if then else from the script") os.exit() end if(Nstates>64000) then print("If you want to calculate more than 64000 states you have to remove this if then else from the script") print("Furthermore it is recommended that you set the number of bits in the hash key table to a larger number.") print("Change the line psi[i] = NewWavefunction(Nf, Nb, {{basis[i-1],1}})") print("to psi[i] = NewWavefunction(Nf, Nb, {{basis[i-1],1}}, {{\"NBitsKey\",20}}).") os.exit() end TimeStart("Create Determinants") -- Create the first determinant (spin-orbital 1 -- to Nelec filled, Nelec+1 to Nf empty). -- Determinants are stored as strings with 1 -- meaning occupied and 0 meaning empty str="" for i=1,Nelec do str=str..1 end for i=1,Nf-Nelec do str=str..0 end -- Search possible many-body states newstr={}; newstr[0]=str basis={}; for i=1,Nstates do basis[i]=str end kprev={} ; kprev[1]=0 ; kprev[2]=0 ; k=0 ; e=1 for i=1,Nf do for l=kprev[i],kprev[i+1] do for j=i+1,Nf do k=k+1 newstr[k]=swap_char(i,j,newstr[l]) info=0 for g=1,Nstates do if (newstr[k] == basis[g]) then info=1 end end if (info == 0) then e=e+1 basis[e]=newstr[k] end end if (e == Nstates) then break end end kprev[i+2]=k end -- END of search TimeEnd("Create Determinants") -- print the possible many-body single Slater -- determinant states print("--> List of possible single Slater determinants which span the basis for all many body states:") for i=1,(Nstates) do print(string.format("%5i |%s>",i,basis[i])) end TimeStart("Create operators in second quantization") OppSz = NewOperator("Sz" ,Nf,IndexUp,IndexDn) OppLz = NewOperator("Lz" ,Nf,IndexUp,IndexDn) OppSsqr = NewOperator("Ssqr" ,Nf,IndexUp,IndexDn) OppLsqr = NewOperator("Lsqr" ,Nf,IndexUp,IndexDn) OppJz = NewOperator("Jz" ,Nf,IndexUp,IndexDn) OppJsqr = NewOperator("Jsqr" ,Nf,IndexUp,IndexDn) Oppldots= NewOperator("ldots",Nf,IndexUp,IndexDn) SlaterInts={} OppFk={} Nk=l+1 for j=1,Nk do for i = 1,Nk do SlaterInts[i]=0 end SlaterInts[j]=1 OppFk[j] = NewOperator("U", Nf, IndexUp, IndexDn, SlaterInts) end TimeEnd("Create operators in second quantization") TimeStart("Create operators in matrix form") --- create the set of wavefunctions, using the obtained states psi={} for i=1,Nstates do psi[i] = NewWavefunction(Nf,Nb,{{basis[i],1}}) end print("\n=============================================================") print("The Sz operator on a basis Single slater determinants for a shell with l = "..l.." and a filling of "..Nelec.." electrons is:") for i = 1, Nstates do io.write(string.format("%5i |%s> ",i,basis[i])) for j = 1, Nstates do io.write(string.format("%5.2f ",psi[i] * OppSz * psi[j])) end io.write("\n") end print("\n=============================================================") print("The Lz operator on a basis Single slater determinants for a shell with l = "..l.." and a filling of "..Nelec.." electrons is:"); for i = 1, Nstates do io.write(string.format("%5i |%s> ",i,basis[i])) for j = 1, Nstates do io.write(string.format("%5.2f ",psi[i] * OppLz * psi[j])); end io.write("\n"); end print("\n=============================================================") print("The S^2 operator on a basis Single slater determinants for a shell with l = "..l.." and a filling of "..Nelec.." electrons is:") for i = 1, Nstates do io.write(string.format("%5i |%s> ",i,basis[i])) for j = 1, Nstates do io.write(string.format("%5.2f ",psi[i] * OppSsqr * psi[j])) end io.write("\n") end print("\n=============================================================") print("The L^2 operator on a basis Single slater determinants for a shell with l = "..l.." and a filling of "..Nelec.." electrons is:") for i = 1, Nstates do io.write(string.format("%5i |%s> ",i,basis[i])) for j = 1, Nstates do io.write(string.format("%5.2f ",psi[i] * OppLsqr * psi[j])) end io.write("\n") end print("\n=============================================================") print("The Coulomb operator for a shell with l = "..l.." is given by "..Nk.." different operators depending on the angular momentum of the expansion of 1/|r1-r2| in spherical Harmonics") for k=1,Nk do print("=============================================================") print("F["..(2*(k-1)).."]") for i = 1, Nstates do io.write(string.format("%5i |%s> ",i,basis[i])) for j = 1, Nstates do io.write(string.format("%5.2f ",psi[i] * OppFk[k] * psi[j])) end io.write("\n") end end TimeEnd("Create operators in matrix form") print("\n=============================================================") TimePrint()