# DisplacedSqueezed state inner product

in this paper the authors describe in equation 33 a generic way to compute the inner product between DSN states and then in the appendix in equation A5 a compact form between two displaced squeezed states as shown in the fig below:

when i try to implement this equation using straightforward numpy, the squeezing part is working perfectly as it should be and also as mentioned in your paper. The displacement part is also correct and it matches what strawberryfields produces. “calculating the inner product between two displaced states or two squeezed states”.

However, the inner product between two DS states doesn’t match the output from equation A5 and the output from strawberryfields is much more realistic in terms of separability. for example r_1 = 1, \ \ r_2=0.-2, \\ d_1=0.4,\ \ d_2=-0.4
the term |<\psi_1|\psi_2>|^2 is very low using both of the fock backend and gaussian backend. but it doesn’t match the output from equation A5.

Do you have any ideas or any insights to why this happens? @nathan @Maria_Schuld

Hi @kareem_essafty — Could you share the code you used to calculate the overlaps? Also, just to make sure, the equation you write is for \langle \psi_1|\psi_2 \rangle but SF will likely give you the modulus squared of this, namely | \langle \psi_1|\psi_2 \rangle |^2

Thanks for your response. Here’s the code i’m using sorry about the print statements but it helps me keep tracking of values

def DS(dis_1, theta_1, dis_2, theta_2, mag1=0.0, phi_1=0, mag2 =0.0, phi_2=0):

z1 = dis_1*np.exp(1j*theta_1)

z2 = dis_2*np.exp(1j*theta_2)
print("z1: ",z1)

print("z2: ",z2)

sigma = (np.cosh(mag2) * np.cosh(mag1)) - (np.exp(1j*(phi_2-phi_1)) * np.sinh(mag2)*np.sinh(mag1))

print("sigma: ",sigma)

eta_21 = ((z2 - z1)*np.cosh(mag2)) - ((np.conj(z2) - np.conj(z1)) * np.exp(1j*phi_2)*np.sinh(mag2))
print(eta_21)

eta_12 = ((z1 - z2)*np.cosh(mag1)) - ((np.conj(z1) - np.conj(z2)) * np.exp(1j*phi_1)*np.sinh(mag1))
print(eta_12)

term_1 = np.sqrt(sigma)
print(term_1)

term_2 = (eta_21 * np.conj(eta_12))/(2 * sigma)
print("term_2: ",term_2)

term_3 = 0.5*((z2 * np.conj(z1)) - (np.conj(z2)*z1))

return  np.exp(term_2+term_3)*(1/term_1)


i use the ket() method to get \psi and then do something like this:

np.dot(state_2.conj().T,state_1)

so it’s not the squaring issue

Hi @kareem_essafty could you also share your SF code and the particular parameters you are using?

import numpy as np
import strawberryfields as sf
from strawberryfields.ops import *

sf.hbar=2
prog = sf.Program(1)
eng = sf.Engine("fock", backend_options={'cutoff_dim': 40})

with prog.context as q:
DisplacedSqueezed(0,0,.5,0.0) | q[0]
#DisplacedSqueezed(0.0,0,0,0) | q[1]
#DisplacedSqueezed(0.1,1,1,3) | q[2]

state_1= eng.run(prog).state

prog2 = sf.Program(1)
eng2 = sf.Engine("fock", backend_options={'cutoff_dim': 40})

with prog2.context as q:
DisplacedSqueezed(2,0,1.,0.0) | q[0]

state_2 = eng2.run(prog2).state


np.dot(state_1.ket().coj().T, state_2.ket())

I avoided the dm method and tried to implement everything from scratch to make sure i’m on the right track

Hi @kareem_essafty — I verified the numbers coming from strawberry fields and they are correct. I think the reason you are getting different answers is that the paper you cite uses a different convention for the squeezing operator. They define it as while we define it as
Thus our z is their minus \zeta. I’d encourage you to always verify the conventions page of Strawberry Fields against any external source to make sure you are always using the same definitions…

1 Like

Thank you so much!
I have been searching for a solution for a quite long time . I think there should be like a fixed standard as we have in the qubit system.
one final thing when i add the sign in front of mag or the \zeta it works perfectly except for the imaginary part they are identical except for the sign. but when I take the abs they are of course identical. should I change something else in the function above?

again thanks a lot for your response

1 Like

Unfortunately the field of CV quantum computing is rife with different sign conventions. Even hbar can change from chapter to chapter of the same thesis! Our solution here was to be very clear about our conventions on the SF conventions page, as @Nicolas_Quesada mentioned.

Regarding your final sign issue, if you get that the imaginary part has the opposite sign, that means you are getting the complex conjugate of what you expect. Can you confirm that you are comparing the desired inner products correctly? i.e., \langle x \vert y \rangle=\langle y \vert x \rangle^*

1 Like

I figured it out and forgot to check the post since i was a bit thrilled . thanks for your response and Merry Christmas everyone

3 Likes