Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

關於 QITE 腳本的一些疑問 #6

Open
IvanaGyro opened this issue Aug 2, 2023 · 8 comments
Open

關於 QITE 腳本的一些疑問 #6

IvanaGyro opened this issue Aug 2, 2023 · 8 comments

Comments

@IvanaGyro
Copy link
Collaborator

evs.append(A_.Es(ops))
les.append(A_.overlap(A))

上面這兩行都會改變 A_ 的值,這是預期中的事嗎?另外

np.random.seed(0)
par_Aop = np.random.randn(16)

為什麼這裡要給亂數產生器設定一個常數 seed?故意要讓下面產生的亂數每一次執行都一樣嗎?

@IvanaGyro
Copy link
Collaborator Author

evs.append(A_.Es(ops)) 
 les.append(A_.overlap(A)) 

保留上面兩行的結果
Figure_1

刪除上面兩行的結果
Figure_2

@hunghaoti
Copy link
Owner

evs.append(A_.Es(ops))
les.append(A_.overlap(A))

上面這兩行都會改變 A_ 的值,這是預期中的事嗎?另外

np.random.seed(0)
par_Aop = np.random.randn(16)

為什麼這裡要給亂數產生器設定一個常數 seed?故意要讓下面產生的亂數每一次執行都一樣嗎?
1、上面那二行確實會改變A_,但這樣的改變不會對它的物理狀態影響。不過他這麼寫確實另人疑慮。
2、固定random seed 確實是為了讓他產生一樣的數字,不過這一行應該不會影響太大。

@hunghaoti
Copy link
Owner

evs.append(A_.Es(ops)) 
 les.append(A_.overlap(A)) 

保留上面兩行的結果 Figure_1

刪除上面兩行的結果 Figure_2

1、二次執行出不一樣的結果,我想是因為使用measurement的方法估計probabitly amplitude都會有一點誤差,所以其實一樣的code執行二次,可能都會有不太一樣的結果。
2、想詢問一下上面的結果是使用Fujitsu計算的結果嗎?
3、如果方便的話能否將上圖修正為:
(1). title改成Fujitsu result
(2). y軸label改成energy, x軸改為imaginary time
(3). 改成scatter plot。

@IvanaGyro
Copy link
Collaborator Author

IvanaGyro commented Aug 3, 2023

兩次結果不同不單只是 measurement 造成的。下圖是我把 measurement 關掉,在那兩行沒有註解的情況下,直接算機率得到的。
開兩行

這張則是註解掉那兩行得到的
註解兩行

把它們合併成一張圖,藍色是沒有註解時的,橘色是有註解時的。橘色的能量明顯比藍色還要更低。
combine

可以透過以下程式碼驗證 A_.Es()A_.overlap() 會有副作用。

import copy

import cirq
import numpy as np
from qmps.represent import ShallowFullStateTensor
from qmps.tools import unitary_to_tensor
from xmps.iMPS import iMPS

U = ShallowFullStateTensor(2, np.ones(15), 'U')
state = iMPS([unitary_to_tensor(cirq.unitary(U))]).left_canonicalise()

print('----- side effect of iMPS.Es() -----')
copy_state = copy.deepcopy(state)
state.Es([])
print(state.data[0] == copy_state.data[0])


print('----- side effect of iMPS.overlap() -----')
other = iMPS([unitary_to_tensor(cirq.unitary(U))]).left_canonicalise()
copy_state = copy.deepcopy(state)
state.overlap(other)
print(state.data[0] == copy_state.data[0])

運行結果:

----- side effect of iMPS.Es() -----
[[[False False]
  [False False]]

 [[False False]
  [False False]]]
----- side effect of iMPS.overlap() -----
[[[False False]
  [False False]]

 [[False False]
  [False False]]]

往上追 iMPS 的程式碼可以看到,在 iMPS.Es() 的部分,如果沒有給 c (canonicalisation of current state),現在的 state 會再被 canonicalise 一次。

https://github.com/fergusbarratt/xmps/blob/0fe1c7ec93425fcbfcd2bd411599c645b1edce62/xmps/iMPS.py#L443-L481

    def Es(self, ops, c=None):
        """E: calculate expectation of single site operator


        :param op: operator to compute expectation of
        :param c: canonicalisation of current state.
                  Should be in ['l', 'm', 'r', None].
                  If None, decompose to vidal then use that.
        """
        ret = []
        if c == 'm':
            L = self.L
            A = self.data[0]
            for op in ops:
                ret.append(real_if_close(sum(L @ A * tensordot(op, C(A) @ L, [1, 0]))))
            return ret
        if c == 'r':
            L = self.L
            A = self.data[0]
            for op in ops:
                ret.append(real_if_close(sum(A * tensordot(op, L**2 @ C(A), [1, 0]))))
            return ret
        if c == 'l':
            L = self.L
            A = self.data[0]
            for op in ops:
                ret.append(real_if_close(sum(A @ L**2 * tensordot(op, C(A), [1, 0]))))
            return ret


        if c is None:
            G, L = self.canonicalise(to_vidal=True).data[0]
            circle = tr(G.dot(L).dot(L).dot(H(G)).dot(L).dot(L), axis1=1, axis2=3)
            #  - L - G - L -
            # |      |0     |       |0
            # |    circle   |,      op
            # |      |1     |       |1
            #  - L - G - L -
            for op in ops:
                ret.append(real_if_close(tr(circle @ op)))
            return ret

iMPS.overlap() 的部分,則是不論如何都會再執行 left_canonicalise() 一次。

https://github.com/fergusbarratt/xmps/blob/0fe1c7ec93425fcbfcd2bd411599c645b1edce62/xmps/iMPS.py#L408-L410

    def overlap(self, other):
        A, B = self.left_canonicalise()[0], other.left_canonicalise()[0]
        return np.abs(Map(A, B).left_fixed_point()[0])**2

不論是 left_canonicalise() 還是 canonicalise() 都會修改當前的 state。left_canonicalise() 會呼叫 canonicalise() 然後 canonicalise() 不會檢查當前狀態,會直接修改當前的 state。

https://github.com/fergusbarratt/xmps/blob/0fe1c7ec93425fcbfcd2bd411599c645b1edce62/xmps/iMPS.py#L377-L392

        if hand is 'r':
            self.data[0] = G_ @ L_
        elif hand is 'l':
            self.data[0] = L_ @ G_
        elif hand is 'm':
            sqrtL_ = diag(sqrt(L))
            self.data[0] = sqrtL_ @ G_ @ sqrtL_


        if to_vidal:
            return ivMPS([(G_, L_)])
        else:
            self.canonical = hand
            return self


    def left_canonicalise(self):
        return self.canonicalise('l')

@hunghaoti
Copy link
Owner

了解,看起來的確會有影響。詢問一下關掉measurement的結果是不是也是在Fujitsu上運行的結果?

@IvanaGyro
Copy link
Collaborator Author

上面都不是用 Fujitsu 的 backend 運作的結果。但現在 fujitsu 分支上已經有可以用 fujitsu 提供的 backend 運行的腳本,只是一次只能啟動一個 node。可以一次啟動多個 node 的程式碼我還沒改好。

@IvanaGyro
Copy link
Collaborator Author

另外我有些納悶,已經 canonicalise 過的 tensor network 就算再次 canonicalise 不是應該得到一樣的結果嗎?

@hunghaoti
Copy link
Owner

OK了解,確實canonicalize不應該影響到計算結果。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants