from __future__ import division, print_function, absolute_import, unicode_literals
import numpy as np
import pygsti
from pygsti.tools import matrixmod2 # module moved
import pygsti.tools.symplectic as symplectic # and replace 'circuit' with 'symplectic' most places below
/Users/enielse/research/pyGSTi/packages/pygsti/tools/matrixtools.py:23: UserWarning: Could not import Cython extension - falling back to slower pure-python routines _warnings.warn("Could not import Cython extension - falling back to slower pure-python routines")
This is just tests, and doesn't give any info on what of this is. This should run most of the functions in symplectic.py, but currently not absolutely everything.
# Tests that check the symplectic random sampler, check_symplectic, the convention converter,
# and the symplectic form constructing function are working.
# Randomly have odd or even dimension (so things might behave differently for odd or even)
n = 4 + np.random.randint(0,2)
omega_S = symplectic.symplectic_form(n,convention='standard')
#print(omega_S)
omega_DS = symplectic.symplectic_form(n,convention='directsum')
#print(omega_DS)
omega_DStoS = symplectic.change_symplectic_form_convention(omega_DS)
assert(np.array_equal(omega_S,omega_DStoS))
omega_StoDS = symplectic.change_symplectic_form_convention(omega_S,outconvention='directsum')
assert(np.array_equal(omega_DS,omega_StoDS))
# Pick a random symplectic matrix in the standard convention and check it is symplectic
s_S = symplectic.random_symplectic_matrix(n)
assert(symplectic.check_symplectic(s_S))
# Pick a random symplectic matrix in the directsum convention and check it is symplectic
s_DS = symplectic.random_symplectic_matrix(n,convention='directsum')
assert(symplectic.check_symplectic(s_DS,convention='directsum'))
# Convert the directsum convention to the standard convention and check the output is symplectic in new convention
s_DStoS = symplectic.change_symplectic_form_convention(s_DS)
assert(symplectic.check_symplectic(s_DStoS,convention='standard'))
# Convert back to the directsum convention, and check the original matrix is recovered.
s_DStoStoDS = symplectic.change_symplectic_form_convention(s_DStoS,outconvention='directsum')
assert(np.array_equal(s_DS,s_DStoStoDS))
# Check that the inversion function is working.
sin = symplectic.inverse_symplectic(s_S)
assert(np.array_equal(matrixmod2.dotmod2(sin,s_S),np.identity(2*n,int)))
assert(np.array_equal(matrixmod2.dotmod2(s_S,sin),np.identity(2*n,int)))
# Check the Clifford sampler runs.
s, p = symplectic.random_clifford(n)
# Check that a randomly sampled Clifford is a valid Clifford
assert(symplectic.check_valid_clifford(s,p))
# Check the inverse Clifford function runs, and gives a valid Clifford
sin, pin = symplectic.inverse_clifford(s,p)
assert(symplectic.check_valid_clifford(sin,pin))
# Check the symplectic matrix part of the inverse Clifford works
assert(np.array_equal(matrixmod2.dotmod2(sin,s),np.identity(2*n,int)))
assert(np.array_equal(matrixmod2.dotmod2(s,sin),np.identity(2*n,int)))
# Check that the composite Clifford function runs, and works correctly in the special case whereby
# one Clifford is the inverse of the other.
scomp, pcomp = symplectic.compose_cliffords(s,p,sin,pin)
assert(np.array_equal(scomp,np.identity(2*n,int)))
assert(np.array_equal(pcomp,np.zeros(2*n,int)))
# Check the p returned is unchanged when the seed is valid.
pvalid = symplectic.construct_valid_phase_vector(s,p)
assert(np.array_equal(p,pvalid))
# Check that p returned is a valid Clifford when the input pseed is not
pseed = (p - 1) % 2
pvalid = symplectic.construct_valid_phase_vector(s,pseed)
assert(symplectic.check_valid_clifford(s,pvalid))
# OLD NOTE: symplectic_representation -> standard_symplectic_representations
# and return value is a *single* dictionary holding (smatrix,pvector) tuples
# Get the full hard-coded symplectic rep dictionaries
srep_dict = symplectic.standard_symplectic_representations()
assert('CNOT' in list(srep_dict.keys()))
# Get the a subset of the full hard-coded symplectic rep dictionaries
srep_dict = symplectic.standard_symplectic_representations(['CNOT'])
assert('CNOT' in list(srep_dict.keys()))
# Define a Clifford circuit to test `composite_clifford_from_clifford_circuit`
glist = []
glist.append(pygsti.obj.Label('CPHASE',(0,1)))
glist.append(pygsti.obj.Label('SWAP',(0,3)))
glist.append(pygsti.obj.Label('H',(2)))
glist.append(pygsti.obj.Label('P',(2)))
glist.append(pygsti.obj.Label('HP',(0)))
glist.append(pygsti.obj.Label('PH',(2)))
glist.append(pygsti.obj.Label('HPH',(1)))
glist.append(pygsti.obj.Label('CNOT',(2,0)))
#OLD: c = circuit.Circuit(gate_list=glist,n=n)
c = pygsti.obj.Circuit(gatestring=glist,num_lines=n)
# This checks the function runs when we don't provide a symplectic library.
s, p = symplectic.composite_clifford_from_clifford_circuit(c)
# This checks the function runs when we do provide a symplectic library.
# OLD: sdict, pdict = circuit.symplectic_representation()
# OLD: s, p = symplectic.composite_clifford_from_clifford_circuit(c,s_dict = sdict, p_dict = pdict)
srep_dict = symplectic.standard_symplectic_representations()
s, p = symplectic.composite_clifford_from_clifford_circuit(c,srep_dict)
# Define a Clifford circuit that composes to the identity
glist = []
glist.append(pygsti.obj.Label('CPHASE',(0,1)))
glist.append(pygsti.obj.Label('CPHASE',(1,0)))
glist.append(pygsti.obj.Label('H',(2)))
glist.append(pygsti.obj.Label('H',(2)))
glist.append(pygsti.obj.Label('X',(3)))
glist.append(pygsti.obj.Label('X',(3)))
c = pygsti.obj.Circuit(gatestring=glist,num_lines=n)
# Check the composite clifford functions says this circuit is the identity.
s, p = symplectic.composite_clifford_from_clifford_circuit(c)
assert(np.array_equal(scomp,np.identity(2*n,int)))
assert(np.array_equal(pcomp,np.zeros(2*n,int)))
H = (1/np.sqrt(2))*np.array([[1.,1.],[1.,-1.]],complex)
s, p = symplectic.unitary_to_symplectic_1Q(H)
assert(np.array_equal(s,srep_dict['H'][0])) # OLD asserts used s_dict['H']
assert(np.array_equal(p,srep_dict['H'][1])) # or p_dict['H']
s, p = symplectic.unitary_to_symplectic(H)
assert(np.array_equal(s,srep_dict['H'][0]))
assert(np.array_equal(p,srep_dict['H'][1]))
CNOT = np.array([[1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,0.,1.],[0.,0.,1.,0.]],complex)
s, p = symplectic.unitary_to_symplectic_2Q(CNOT)
assert(np.array_equal(s,srep_dict['CNOT'][0]))
assert(np.array_equal(p,srep_dict['CNOT'][1]))
s, p = symplectic.unitary_to_symplectic(CNOT)
assert(np.array_equal(s,srep_dict['CNOT'][0]))
assert(np.array_equal(p,srep_dict['CNOT'][1]))