def test_no_touch_single_sqrt_iswap_inv(): a, b = cirq.LineQubit.range(2) assert_optimizes( use_sqrt_iswap_inv=True, before=cirq.Circuit([ cirq.Moment([cirq.SQRT_ISWAP_INV(a, b).with_tags('mytag')]), ]), expected=cirq.Circuit([ cirq.Moment([cirq.SQRT_ISWAP_INV(a, b).with_tags('mytag')]), ]), )
def cphase_symbols_to_sqrt_iswap(a, b, turns): """Version of cphase_to_sqrt_iswap that works with symbols. Note that the formulae contained below will need to be flattened into a sweep before serializing. """ theta = sympy.Mod(turns, 2.0) * sympy.pi # -1 if theta > pi. Adds a hacky fudge factor so theta=pi is not 0 sign = sympy.sign(sympy.pi - theta + 1e-9) # For sign = 1: theta. For sign = -1, 2pi-theta theta_prime = (sympy.pi - sign * sympy.pi) + sign * theta phi = sympy.asin(np.sqrt(2) * sympy.sin(theta_prime / 4)) xi = sympy.atan(sympy.tan(phi) / np.sqrt(2)) yield cirq.rz(sign * 0.5 * theta_prime).on(a) yield cirq.rz(sign * 0.5 * theta_prime).on(b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(-sign * 0.5) yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.rx(-2 * phi).on(a) yield cirq.SQRT_ISWAP(a, b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(sign * 0.5)
def test_optimizes_single_inv_sqrt_iswap_require3(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) assert_optimization_not_broken(c, required_sqrt_iswap_count=3) c = cirq.optimize_for_target_gateset( c, gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=3)) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3
def test_optimizes_single_inv_sqrt_iswap_require3(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) assert_optimization_not_broken(c, required_sqrt_iswap_count=3) cirq.MergeInteractionsToSqrtIswap( required_sqrt_iswap_count=3).optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3
def test_optimizes_single_iswap_require2(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) # Minimum 1 sqrt-iSWAP but 2 possible assert_optimization_not_broken(c, required_sqrt_iswap_count=2) c = cirq.optimize_for_target_gateset( c, gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=2), ignore_failures=False ) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
def test_optimizes_single_inv_sqrt_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) assert_optimization_not_broken(c) c = cirq.optimize_for_target_gateset( c, gateset=cirq.SqrtIswapTargetGateset(), ignore_failures=False ) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1
def test_simplifies_sqrt_iswap_inv(): a, b = cirq.LineQubit.range(2) assert_optimizes( use_sqrt_iswap_inv=True, before=cirq.Circuit([ # SQRT_ISWAP**8 == Identity cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP_INV(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), ]), expected=cirq.Circuit([cirq.Moment([cirq.SQRT_ISWAP_INV(a, b)])]), )
def test_optimizes_single_inv_sqrt_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) assert_optimization_not_broken(c) with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2): cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1
def test_works_with_tags(): a, b = cirq.LineQubit.range(2) assert_optimizes( before=cirq.Circuit([ cirq.Moment([cirq.SQRT_ISWAP(a, b).with_tags('mytag1')]), cirq.Moment([cirq.SQRT_ISWAP(a, b).with_tags('mytag2')]), cirq.Moment([cirq.SQRT_ISWAP_INV(a, b).with_tags('mytag3')]), ]), expected=cirq.Circuit([cirq.Moment([cirq.SQRT_ISWAP(a, b)])]), )
def iswap_to_sqrt_iswap(a, b, turns): """Implement the evolution of the hopping term using two sqrt_iswap gates and single-qubit operations. Output unitary: [1 0 0 0], [0 c is 0], [0 is c 0], [0 0 0 1], where c = cos(t * np.pi / 2) and s = sin(t * np.pi / 2). Args: a: the first qubit b: the second qubit turns: Exponent that specifies the evolution time in number of rotations. """ yield cirq.Z(a)**0.75 yield cirq.Z(b)**0.25 yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.Z(a)**(-turns / 2 + 1) yield cirq.Z(b)**(turns / 2) yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.Z(a)**0.25 yield cirq.Z(b)**-0.25
def cphase_to_sqrt_iswap(a, b, turns): """Implement a C-Phase gate using two sqrt ISWAP gates and single-qubit operations. The circuit is equivalent to cirq.CZPowGate(exponent=turns). Output unitary: [1 0 0 0], [0 1 0 0], [0 0 1 0], [0 0 0 e^{i turns pi}]. Args: a: the first qubit b: the second qubit turns: Exponent specifying the evolution time in number of rotations. """ theta = (turns % 2) * np.pi if 0 <= theta <= np.pi: sign = 1.0 theta_prime = theta elif np.pi < theta < 2 * np.pi: sign = -1.0 theta_prime = 2 * np.pi - theta if np.isclose(theta, np.pi): # If we are close to pi, just set values manually to avoid possible # numerical errors with arcsin of greater than 1.0 (Ahem, Windows). phi = np.pi / 2 xi = np.pi / 2 else: phi = np.arcsin(np.sqrt(2) * np.sin(theta_prime / 4)) xi = np.arctan(np.tan(phi) / np.sqrt(2)) yield cirq.rz(sign * 0.5 * theta_prime).on(a) yield cirq.rz(sign * 0.5 * theta_prime).on(b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(-sign * 0.5) yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.rx(-2 * phi).on(a) yield cirq.SQRT_ISWAP(a, b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(sign * 0.5) # Corrects global phase yield cirq.global_phase_operation(np.exp(sign * theta_prime * 0.25j))