initial commit
This commit is contained in:
parent
6f908454fa
commit
4c028e74e2
15 changed files with 3110 additions and 0 deletions
83
scripts/grraph_state_cuts.py
Normal file
83
scripts/grraph_state_cuts.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import numpy as np
|
||||
from itertools import product, combinations
|
||||
|
||||
I=np.array([[1,0],[0,1]],complex)
|
||||
X=np.array([[0,1],[1,0]],complex)
|
||||
Y=np.array([[0,-1j],[1j,0]],complex)
|
||||
Z=np.array([[1,0],[0,-1]],complex)
|
||||
paulis=[I,X,Y,Z]
|
||||
labels=['I','X','Y','Z']
|
||||
|
||||
def kron_all(ops):
|
||||
out=ops[0]
|
||||
for op in ops[1:]: out=np.kron(out,op)
|
||||
return out
|
||||
|
||||
def graph_state(n, edges):
|
||||
psi=np.ones(2**n,complex)/np.sqrt(2**n)
|
||||
# basis index bits qubit 0..n-1 as MSB? phase invariant consistent
|
||||
for idx in range(2**n):
|
||||
bits=[(idx>>(n-1-q))&1 for q in range(n)]
|
||||
phase=1
|
||||
for a,b in edges:
|
||||
if bits[a]*bits[b]: phase*=-1
|
||||
psi[idx]*=phase
|
||||
return psi
|
||||
|
||||
def corr_tensor(psi,n):
|
||||
coeff={}
|
||||
for inds in product(range(4), repeat=n):
|
||||
op=kron_all([paulis[i] for i in inds])
|
||||
val=np.vdot(psi, op@psi)
|
||||
if abs(val)>1e-9:
|
||||
coeff[inds]=float(np.real_if_close(val))
|
||||
return coeff
|
||||
|
||||
def matrix_for_cut(coeff,S,n, source_full=False, target_full=False):
|
||||
Sc=[i for i in range(n) if i not in S]
|
||||
row=[]; col=[]
|
||||
for inds in product(range(4), repeat=len(S)):
|
||||
if all(i==0 for i in inds): continue
|
||||
if source_full and any(i==0 for i in inds): continue
|
||||
row.append(inds)
|
||||
for inds in product(range(4), repeat=len(Sc)):
|
||||
if all(i==0 for i in inds): continue
|
||||
if target_full and any(i==0 for i in inds): continue
|
||||
col.append(inds)
|
||||
M=np.zeros((len(col),len(row))) # target rows, source cols
|
||||
for r,tinds in enumerate(col):
|
||||
for c,sinds in enumerate(row):
|
||||
full=[0]*n
|
||||
for q,ind in zip(S,sinds): full[q]=ind
|
||||
for q,ind in zip(Sc,tinds): full[q]=ind
|
||||
M[r,c]=coeff.get(tuple(full),0.0)
|
||||
return M,row,col
|
||||
|
||||
def partial_rho(psi, keep, n):
|
||||
rho=np.outer(psi, psi.conj()).reshape([2]*n*2)
|
||||
trace=[i for i in range(n) if i not in keep]
|
||||
# trace out from high to low axes
|
||||
for q in sorted(trace, reverse=True):
|
||||
rho=np.trace(rho, axis1=q, axis2=q+rho.ndim//2)
|
||||
d=2**len(keep)
|
||||
return rho.reshape(d,d)
|
||||
|
||||
n=4
|
||||
edges=[(0,1),(1,2),(2,3),(3,0)]
|
||||
psi=graph_state(n,edges)
|
||||
coeff=corr_tensor(psi,n)
|
||||
print('nonzero coeffs', len(coeff))
|
||||
for cutname,S in [('adjacent12|34',[0,1]),('diagonal13|24',[0,2]),('adjacent14|23',[0,3])]:
|
||||
M,_,_=matrix_for_cut(coeff,S,n)
|
||||
G,_,_=matrix_for_cut(coeff,S,n,source_full=True,target_full=True)
|
||||
norm=np.linalg.svd(M/3, compute_uv=False).sum()
|
||||
rawn=np.linalg.svd(M, compute_uv=False).sum()
|
||||
gnorm=np.linalg.svd(G/3, compute_uv=False).sum()
|
||||
graw=np.linalg.svd(G, compute_uv=False).sum()
|
||||
print('\n',cutname)
|
||||
print('full normalized',norm,'raw',rawn,'sing',np.linalg.svd(M/3,compute_uv=False))
|
||||
print('genuine normalized',gnorm,'raw',graw,'sing',np.linalg.svd(G/3,compute_uv=False))
|
||||
rho=partial_rho(psi,S,n)
|
||||
print('rho eigen',np.linalg.eigvalsh(rho),'max mixed dist',np.linalg.norm(rho-np.eye(4)/4))
|
||||
# list nonzero stabilizers labels
|
||||
# print rows/cols maybe
|
||||
Loading…
Add table
Add a link
Reference in a new issue