state overlap(probability)

How do I use this algorithm? What does that parameter do?
Post Reply
amankumar
Posts: 19
Joined: 17 Apr 2020, 11:14

state overlap(probability)

Post by amankumar »

Hi
I want to know, is there a way to calculate probability to find particle at any site i in up (or down) state?
Like if I have a state \(|\Psi>\) in MPS form and I want to evaluate this quantity \(<\Psi|down_i>\) , where \(|down_i>\) is linear combination of all simple basis state where at site i it is down and at all other site it can be either up or down.
User avatar
Johannes
Site Admin
Posts: 209
Joined: 21 Jul 2018, 12:52
Location: UC Berkeley

Re: state overlap(probability)

Post by Johannes »

Sure! Basically, what you want is
\[P(\sigma_i=\downarrow_i) = \langle \Psi | \downarrow_i\rangle \langle \downarrow_i |\Psi \rangle = Tr_{\mathcal{H}}(|\Psi\rangle \langle \Psi | \downarrow_i\rangle \langle \downarrow_i |) = Tr_{\mathcal{H}_i}(\rho_i |\downarrow_i\rangle \langle \downarrow_i |) = \langle \downarrow_i |\rho_i |\downarrow_i\rangle\]
where \(\rho_i\) is the local density matrix on site \(i\).
In other words, you want to use get_rho_segment and extract the diagonal matrix element for the down state. To get the correct index for the down state, use state_labels, like this:

Code: Select all

rho_i = psi.get_rho_segment([i])
down_idx = psi.sites[i].state_labels['down']
P_down = rho_i[down_idx, down_idx]
amankumar
Posts: 19
Joined: 17 Apr 2020, 11:14

Re: state overlap(probability)

Post by amankumar »

1.) Is there a way to get full \(\rho_i\) in matrix form or do I have to calculate each matrix element separately as you suggested above.

2.) Also can I calculate this quantity \( \langle \Psi | \downarrow_i\rangle \), as one way I think of by taking square root of corresponding density matrix element, but that can root can be positive or negative. I want to know the absolute value.
User avatar
Johannes
Site Admin
Posts: 209
Joined: 21 Jul 2018, 12:52
Location: UC Berkeley

Re: state overlap(probability)

Post by Johannes »

1.) rho_i.to_ndarray(), if you really want to convert to a numpy array.
2) There is not a unique such value, because the density matrix is mixed.
Work it out for a 2-spin system: the probability for the second spin to be down is \(P(\sigma_2 = \downarrow) = \Psi_{\uparrow\downarrow}\Psi_{\uparrow\downarrow}^* + \Psi_{\downarrow\downarrow} \Psi_{\downarrow\downarrow}^*\)
amankumar
Posts: 19
Joined: 17 Apr 2020, 11:14

Re: state overlap(probability)

Post by amankumar »

Can I see my two site reduced density matrix in this below format, where I can get to know about each elements of the matrix.

\(\begin{matrix}
c_{\uparrow_i\uparrow_j\uparrow_i\uparrow_j} & c_{\uparrow_i\uparrow_j\uparrow_i\downarrow_j} & c_{\uparrow_i\uparrow_j\downarrow_i\uparrow_j} &c_{\uparrow_i\uparrow_j\downarrow_i\downarrow_j} \\

c_{\uparrow_i\downarrow_j\uparrow_i\uparrow_j} & c_{\uparrow_i\downarrow_j\uparrow_i\downarrow_j} & c_{\uparrow_i\downarrow_j\downarrow_i\uparrow_j} &c_{\uparrow_i\downarrow_j\downarrow_i\downarrow_j} \\

c_{\downarrow_i\uparrow_j\uparrow_i\uparrow_j} & c_{\downarrow_i\uparrow_j\uparrow_i\downarrow_j} & c_{\downarrow_i\uparrow_j\downarrow_i\uparrow_j} &c_{\downarrow_i\uparrow_j\downarrow_i\downarrow_j} \\

c_{\downarrow_i\downarrow_j\uparrow_i\uparrow_j} & c_{\downarrow_i\downarrow_j\uparrow_i\downarrow_j} & c_{\downarrow_i\downarrow_j\downarrow_i\uparrow_j} &c_{\downarrow_i\downarrow_j\downarrow_i\downarrow_j} \\
\end{matrix}\)


But I get density matrix in block form. Or you can tell me what each element tells, when I use this below line of command

Code: Select all

rho_i.to_ndarray()
Please let me know If you need more information
User avatar
Johannes
Site Admin
Posts: 209
Joined: 21 Jul 2018, 12:52
Location: UC Berkeley

Re: state overlap(probability)

Post by Johannes »

You have indices i,j, so I guess you're looking at two-site density matrices now. It works the same way, though:

Code: Select all

rho_ij = psi.get_rho_segment([i,j])
rho_ij_dense = rho_ij.transpose(['p0', 'p1', 'p0*', 'p1*']).to_ndarray()  # has shape (2, 2, 2, 2)
assert psi.sites[i].state_labels['up'] == 0  # ensure that the single-site indices are ["up", "down"] and not ["down", "up"]
print(rho_ij_dense.reshape(2*2, 2*2))
The transpose ensures the correct order of the legs.
The .reshape(2*2, 2*2) is just grouping the indices on i,j to a single index \(
0=\uparrow_i \uparrow_j; 1=\uparrow_i \downarrow_j; 2=\downarrow_i \uparrow_j; 3=\downarrow_i\downarrow_j
\)
, such that you get a 4x4 matrix instead of a 2x2x2x2 tensor.
amankumar
Posts: 19
Joined: 17 Apr 2020, 11:14

Re: state overlap(probability)

Post by amankumar »

Thank you for the response.
I have another difficulty in this part, I saw source code of get_rho_segment, where sorting is done for segment sites. So If I am evaluating \(\rho_{ij}\), where index \(i>j\), and I will transform it into a \(4\times 4\) matrix. So, now I am interested in \(\rho_{ji}\) density matrix, which should be transpose of \(\rho_{ij}\), but I get the same \(\rho_{ij}\).
So I wants to confirm this, to fix the convention of density matrices, I am forcing this kind of condition:

Code: Select all

rho_ij=psi.get_rho_segment([i,j]).transpose(['p0', 'p1', 'p0*', 'p1*']).to_ndarray().reshape(2*2, 2*2)
if (i>j):
    rho_ij=rho_ij.T  #which is transpose, so I am considering, tenpy will be evaluating rho_ji for case of i>j, as sorting is done implicitly in code. 
So, please let me know, If I am doing something wrong, or is there other way to consider such kind of convention.

Thank you
User avatar
Johannes
Site Admin
Posts: 209
Joined: 21 Jul 2018, 12:52
Location: UC Berkeley

Re: state overlap(probability)

Post by Johannes »

You need to transpose at the right position, namely before you start grouping/reshaping the legs.
psi.get_rho_segment([i,j]) returns a 4-leg tensor with labels ('p0', 'p1', 'p0*', 'p1*') for (ket left, ket right, bra left, bra right).
Grouping the legs will give you two legs '(p0.p1)', '(p0*.p1*)', so a simple .T in the end will give you '(p0*.p1*)', '(p0.p1)'.
However, what you want is '(p1.p0)', '(p1*.p0*)', so the correct way is:

Code: Select all

rho_ij = psi.get_rho_segment([i,j])
if i <= j:
     rho_ij.itranspose(['p0', 'p1', 'p0*', 'p1*'])
else:
     rho_ij.itranspose(['p1', 'p0', 'p1*', 'p0*'])
rho_ij = rho_ij.to_ndarray().reshape(2*2, 2*2)
Post Reply