pkozlows / fci

0 stars 0 forks source link

implementing second quantization #16

Closed pkozlows closed 1 year ago

pkozlows commented 1 year ago

https://github.com/pkozlows/fci/blob/d37808e08d16b441d7845ff68fc15b1e4f2ea437/questions/2-24.pdf

pkozlows commented 1 year ago

I understand that something like the linked first expression in first quantization can be thought of in terms of colum and exchange ints, but How would I think of something like this in terms of collab and exchange ints or in terms of second quantization?

pkozlows commented 1 year ago

I'm refering to case 2 for 2e- ops in the attached image.

pkozlows commented 1 year ago

PXL_20230217_042732852.jpg

Walter-Feng commented 1 year ago

Usually + for coulomb, - for exchange, and as we went through multiple times, the sign comes from permutation of operators.

It’s relatively hard for me to describe “why makes second quantization, a second quantization”. You can only write the equations, solve the commutation relations and reduce the terms, will you get comfortable with second quantization. I would prefer getting full understanding of second quantization, which is inevitable in the following steps and future projects, instead of sticking to first quantization and integrals.

If it is anti-commutators that trouble you, you might start from harmonic oscillators that have easier form.

pkozlows commented 1 year ago

I am fairly comfortable with second quantization, and last night I realized how I could use it to implement 1 aand 2-electron ops. I just don't know how to implement second quantization efficiently. For example, to compute the phase factor, I implemented second quantization in the linked function below. However, this implementation involves a lot of loops, which I understand is not very efficient. I don't want to look at your code, but I was wondering if you could give any direction as to how to implement second quantization more efficiently. For example, I know that the Einstein summations are a fairly efficient way of accessing the integrals, but I don't know how to incorporate them with second quantization implementation.

https://github.com/pkozlows/fci/blob/d37808e08d16b441d7845ff68fc15b1e4f2ea437/condon.py#L62

Also, I hope the weather in Pasadena is treating you okay. It was raining pretty hard where I am in Irvine last night.

Walter-Feng commented 1 year ago

Usually permutations and modifying things within two for loops would not be a matter - you can count the total steps and if it’s within 100 operations, they should not be bothering you. Contraction takes time because it’s naively 4-6 layers of for loops, and it will surely be slow.

einsum does not necessarily interact with second quantization or phase factor. If you think it does, then maybe you need to pay a bit more time over second quantization.

Walter-Feng commented 1 year ago

Weather is not affecting - I stay at home anyway ┑( ̄Д  ̄)┍ not that kind of outdoor people

pkozlows commented 1 year ago

I have two main questions for you today. I am in the middle of implementing functions that don't work yet, but I wanted to check with you if their general form is correct, so that I can decide if I need to start over with something new, if that makes sense.

The first question is regarding my implementation of the anti-commutator, with the function linked. It is well commented, so you should be able to figure out the algorithm that I'm trying to use. I'm just wondering whether taking a list of second quantization operators and switching them manually and computing the phase factor that results from each switch is the most efficient way of implementing an anti-commutator. I am thinking that this method could be very slow if I am dealing with a lot of operators, as I will be in this full configuration interaction calculation. I don't really need to manually switch each operator and update the phase factor based off of that; I just need to figure out how many permutations it would take to bring two partners to a rendezvous next to each other. I was searching on the internet as to how to implement this in a simpler way than that which I currently have, but I couldn't find anything. Do you have any tips? https://github.com/pkozlows/fci/blob/920ea6ce664fb8ef1cfc1ef7736d6791340f5393/condon.py#L63

The second question is regarding getting matrix elements in second quantization. My current implementation does this with a lot of nested for loops, and I realize that this could probably be accomplished by einstein summation, but I'm not completely sure how I would do this. I was told I could do it with a contraction by chatgpt lol. I know some basic linnear algebra, but I'm not comfortable with tensor contractions, so maybe it is worth starting with learning that? https://github.com/pkozlows/fci/blob/920ea6ce664fb8ef1cfc1ef7736d6791340f5393/condon.py#L98

pkozlows commented 1 year ago

Also, although it might take me some more time now, I realize that implementing the second quantization is going to be very useful for the future. Second quantization is very elegant on paper, and I imagine that if I implement it correctly it will be very elegant in the code too.

pkozlows commented 1 year ago

https://github.com/sympy/sympy/blob/26f7bdbe3f860e7b4492e102edec2d6b429b5aaf/sympy/physics/secondquant.py

I'm looking through this, This is something I would want to look into or would it be a cheat?

Walter-Feng commented 1 year ago

" I don't really need to manually switch each operator and update the phase factor based off of that; I just need to figure out how many permutations it would take to bring two partners to a rendezvous next to each other. " - This is what I think about this. So basically you implement a sorting algorithm and count the permutations. I directly did bubble sort when I did the phase factor.

Einstein convention should not be that difficult. When you do a matrix-vector multiplication, you write

sum_j A_ij V_j

Then well, I know j will be summed anyway, I can just remove the sum_j. Whenever there are duplicate symbols, they are automatically summed over some discrete space according to the context.

matrix multiplication can also be

sum_j A_ij B_jk -> A_ij B_jk

Tensors are not that complicated, at least for what we will be approaching. You can treat a 4-rank tensor as an object whose element requires 4 arguments to be accessed, just like two arguments for a matrix.

T_ijkl D_kl will then be a summation over k and l. Super simple right? Einstein summation originally involves covariant and contravariant components, which are significantly harder, but no need at this point.

I would say sympy is not necessary. Only permutation of numbers is required for this project - I recall writing coupled cluster equations required me to use an actual operator objects, but nothing too difficult.

pkozlows commented 1 year ago

I was able to use the bubble sort algorithm to implement the anti-commutator for the most part. There are a few edge cases, though, and my brain is getting a little fried trying to figure it out. The edge cases, as you should be able to see in my code, are ones where I insert some operators corresponding to the calculation of one or two electron matrix elements. The function is performing just fine for cases where the computations involve two determinants, though. I was wondering whether you would be able to provide a few hints? :-) could you also take a peak at my conditions on Line 95 and line 104? https://github.com/pkozlows/fci/blob/a5a7d2df7b8a9d3889911c8ad85a3973f91118a2/condon.py#L119 I believe I have a decent understanding of the Einstein summation convention. However, I am not understanding how I can replace nested for loops for the computation of matrix elements with np.einsum, as each individual operator list involves computing the phase factor from the anti-commutator function, which could be zero, one, or a negative one, so I don't see how a generic Einstein summation over the integrals would be possible. For example, something like [(1,0), (0,0), (0,1), (0,1), (0,0), (0,0), (0,1), (1,1)] == 0 even though some things like [0,0,0,0] might not necessarily be zero? Let me know if my notation is too confusing, in which case I am happy to write up something in LaTeX.

pkozlows commented 1 year ago

Also, something like [(1,0), (0,0), (0,1), (0,1), (0,0), (0,0), (0,1), (1,1)] would correspond to <01|a^{\dag}_0a^{\dag}_0a_0a_0|01>.

Walter-Feng commented 1 year ago

You have multiple (0,0), have you checked if ops.index(annhltn) > ops.index(crtn): will apply to all these cases?

pkozlows commented 1 year ago

I completely understand what you are saying; I need to let this marinate in my had a little longer before I can figure out how to implement it.