OpenFermion icon indicating copy to clipboard operation
OpenFermion copied to clipboard

Faster normal_ordered() suggestion

Open eul94458 opened this issue 4 years ago • 2 comments

It is about the function normal_ordered_ladder_term().

normal_ordered_ladder_term

I realized that we can actually break the layer of for j in range(i, 0, -1): .

Since if no action at the certain j th index, it implies everything in front of that is well-ordered and every loops afterward are redundant.

I tried in my code and it seems no difference in terms of result, but gain 25% improved performance.

Can anyone verify this?

update: Oh I saw the problem. I haven't account for the situation list 3^ 2^ 1 0 9^, which it is necessary to put 9^ in front of 3^. So simply just can't break the scanning until it scans the whole line.

update: No. I am 85% sure that I was right. Say it is in i_1 and looping through j. When all j for i_1 is finished, everything in front of i_1 should be well-order. Same thing applies to i_2, i_3, i_4, ... Anything in front of i_[n-1] is well ordered. If j th component do not need to swap places with (j-1)th in the first place, then there is no place for it to swap, so we can break the j loop.

eul94458 avatar Oct 20 '21 08:10 eul94458

Hi @eul94458 can you be a bit more specific here? maybe with a worked example? Certainly there are a lot of improvements we can apply to this area of the code and it would be great to see performance gains here.

ncrubin avatar Jan 06 '22 17:01 ncrubin

Hi @eul94458 can you be a bit more specific here? maybe with a worked example? Certainly there are a lot of improvements we can apply to this area of the code and it would be great to see performance gains here.

Say there is a fermion operator (6^ 5^ 3 2^ 1 0)

First the program will look at compare (6^, 5^), then it see it is normal ordered, it proceed to next comparison.

Next is (3, 2^), it is not normal ordered, so indices are swaped. New operator will be (6^ 5^ 2^ 3 1 0).

Next it will compare (5^, 2^), and this is normal.

Then (6^ 5^), this is normal too.

And then I notice that we have already compared (6^ 5^) at the very first moment, so this time, the comparison is totally unnecessary and can be skipped.

It might look like this if you want the code.

            # Swap operators if raising on right and lowering on left.
            if right_operator[1] and not left_operator[1]:

            # Handle case when operator type is the same.
            elif right_operator[1] == left_operator[1]:

                # If same two Fermionic operators are repeated,
                # evaluate to zero.
                if parity == -1 and right_operator[0] == left_operator[0]:

                # Swap if same ladder type but lower index on left.
                elif right_operator[0] > left_operator[0]:

                ################## NEW ################
                # Break since everything in the front is well ordered
                else: 
                    break
                #######################################

eul94458 avatar Jan 12 '22 10:01 eul94458