def test_real_coefficients(self): """Test exponential with complex coefficient.""" q = cirq.GridQubit.rect(1, 2) theta = np.random.random() op = 1j * theta * cirq.Z(q[0]) * cirq.Z(q[1]) with self.assertRaisesRegex(ValueError, expected_regex="supports real"): util.exponential(operators=[op])
def test_exponential_commutablility(self): """Test exponential for non-commutable operator.""" q = cirq.GridQubit(0, 0) theta1 = np.random.random() theta2 = np.random.random() with self.assertRaisesRegex(ValueError, expected_regex="non-commutable"): util.exponential( operators=[theta1 * cirq.X(q) + theta2 * cirq.Z(q)])
def test_exponential_complex(self): """Test exponential for complex operators.""" q = cirq.GridQubit.rect(1, 3) theta1 = np.random.random() theta2 = np.random.random() identity = cirq.PauliString({None: cirq.I}) op1 = cirq.Z(q[1]) * cirq.Z(q[2]) op2 = identity circuit = util.exponential(operators=[theta1 * op1, theta2 * op2]) result_gates = [] for moment in circuit: for gate_op in moment: result_gates.append(gate_op) self.assertIsInstance(result_gates[0].gate, cirq.CNotPowGate) self.assertIsInstance(result_gates[1].gate, cirq.ZPowGate) self.assertIsInstance(result_gates[2].gate, cirq.CNotPowGate) self.assertIsInstance(result_gates[3].gate, cirq.XPowGate) self.assertIsInstance(result_gates[4].gate, cirq.ZPowGate) self.assertIsInstance(result_gates[5].gate, cirq.XPowGate) self.assertIsInstance(result_gates[6].gate, cirq.ZPowGate) # The exponentiation of identity should not be on q[0], but on q[1]. for i in range(3, 7): self.assertEqual(result_gates[i].qubits, (q[1],)) ground_truth_unitary = _exponential(theta1, op1) result_unitary = cirq.unitary(circuit) global_phase = ground_truth_unitary[0][0] / result_unitary[0][0] result_unitary *= global_phase self.assertAllClose(ground_truth_unitary, result_unitary)
def test_allowed_cases(self): """Confirm all valid argument combinations are accepted.""" t_pstr = cirq.X(cirq.GridQubit(0, 0)) t_psum = cirq.X(cirq.GridQubit(0, 0)) + cirq.Z(cirq.GridQubit(0, 1)) for op_list in [[t_pstr], [t_psum], (t_pstr,), (t_psum,)]: for coeff in ["test", sympy.Symbol("test"), 0.5]: for coeff_inp in [[coeff], (coeff,), np.array([coeff])]: _ = util.exponential(op_list, coefficients=coeff_inp)
def test_exponential_simple(self): """Test exponential for a simple operator.""" q = cirq.GridQubit(0, 0) for op in [cirq.X, cirq.Y, cirq.Z]: theta = np.random.random() circuit = util.exponential(operators=[theta * op(q)]) ground_truth_unitary = _exponential(theta, op(q)) self.assertAllClose(ground_truth_unitary, cirq.unitary(circuit))
def test_serializability(self): """Test exponential with serializer.""" q = cirq.GridQubit.rect(1, 2) theta = np.random.random() identity = cirq.PauliString({None: cirq.I}) op1 = theta * cirq.Z(q[0]) * cirq.Z(q[1]) op2 = theta * identity circuit = util.exponential(operators=[op1, op2]) util.convert_to_tensor([circuit])
def test_exponential_simple(self): """Test exponential for a simple operator.""" q = cirq.GridQubit(0, 0) for op in [cirq.X, cirq.Y, cirq.Z]: theta = np.random.random() circuit = util.exponential(operators=[theta * op(q)]) # TODO(jaeyoo) : remove factor 2 if cirq issue is resolved # https://github.com/quantumlib/Cirq/issues/2710 ground_truth_unitary = cirq.unitary(np.exp(-1j * 2 * theta * op(q))) self.assertAllClose(ground_truth_unitary, cirq.unitary(circuit))
def test_exponential_identity(self): """Test exponential for an identity.""" theta = np.random.random() identity = cirq.PauliString({None: cirq.I}) circuit = util.exponential(operators=[theta * identity]) result_gates = [] for moment in circuit: for gate_op in moment: result_gates.append(gate_op.gate) # Because it has no qubit in the total circuit, the default is set to # zeroth qubit. self.assertEqual(circuit.all_qubits(), frozenset({cirq.GridQubit(0, 0)})) self.assertIsInstance(result_gates[0], cirq.XPowGate) self.assertIsInstance(result_gates[1], cirq.ZPowGate) self.assertIsInstance(result_gates[2], cirq.XPowGate) self.assertIsInstance(result_gates[3], cirq.ZPowGate) self.assertAllClose( np.eye(2) * np.exp(-1j * theta), cirq.unitary(circuit))
def test_exponential_complex(self): """Test exponential for complex operators.""" q = cirq.GridQubit.rect(1, 3) theta1 = np.random.random() theta2 = np.random.random() identity = cirq.PauliString({None: cirq.I}) op1 = theta1 * cirq.Z(q[1]) * cirq.Z(q[2]) op2 = theta2 * identity circuit = util.exponential(operators=[op1, op2]) result_gates = [] for moment in circuit: for gate_op in moment: result_gates.append(gate_op) self.assertIsInstance(result_gates[0].gate, cirq.CNotPowGate) self.assertIsInstance(result_gates[1].gate, cirq.ZPowGate) self.assertIsInstance(result_gates[2].gate, cirq.CNotPowGate) self.assertIsInstance(result_gates[3].gate, cirq.XPowGate) self.assertIsInstance(result_gates[4].gate, cirq.ZPowGate) self.assertIsInstance(result_gates[5].gate, cirq.XPowGate) self.assertIsInstance(result_gates[6].gate, cirq.ZPowGate) # The exponentiation of identity should not be on q[0], but on q[1]. for i in range(3, 7): self.assertEqual(result_gates[i].qubits, (q[1],)) # TODO(jaeyoo) : remove factor 2 if cirq issue is resolved # https://github.com/quantumlib/Cirq/issues/2710 ground_truth_unitary = cirq.unitary(np.exp(-1j * 2 * op1)) ground_truth_unitary *= cirq.unitary(np.exp(-1j * op2)) result_unitary = cirq.unitary(circuit) global_phase = ground_truth_unitary[0][0] / result_unitary[0][0] result_unitary *= global_phase self.assertAllClose(ground_truth_unitary, result_unitary)
def test_exponential_error(self): """Test exponential fails on bad inputs.""" test_paulistring = cirq.X(cirq.GridQubit(0, 0)) test_paulisum = cirq.X(cirq.GridQubit(0, 0)) + cirq.Z( cirq.GridQubit(0, 1)) # bad operators with self.assertRaisesRegex(TypeError, expected_regex='not a list'): util.exponential('junk') for bad_op_list in [['junk'], [test_paulistring, 'junk'], [test_paulistring, test_paulisum, 'junk']]: with self.assertRaisesRegex(TypeError, expected_regex='in operators'): util.exponential(bad_op_list) with self.assertRaisesRegex(TypeError, expected_regex="only supports real"): util.exponential([1j * test_paulistring]) # bad coefficients with self.assertRaisesRegex(TypeError, expected_regex='not a list'): util.exponential([test_paulisum], coefficients='junk') for bad_coeff_list in [[None, 1.0], [['junk'], 1.0], [1.0, ['junk']], [1.0, 1j]]: with self.assertRaisesRegex(TypeError, expected_regex='in coefficients'): util.exponential([test_paulistring, test_paulistring], coefficients=bad_coeff_list) with self.assertRaisesRegex(ValueError, expected_regex='should be the same as'): util.exponential([test_paulistring], coefficients=[1.0, 2.0])
def test_exponential_error(self): """Test exponential failed when it should""" test_paulistring = cirq.X(cirq.GridQubit(0, 0)) test_paulisum = cirq.X(cirq.GridQubit(0, 0)) + cirq.Z( cirq.GridQubit(0, 1)) # operators with self.assertRaisesRegex(TypeError, expected_regex='not a list'): util.exponential(operators='junk') with self.assertRaisesRegex(TypeError, expected_regex='PauliString'): util.exponential(operators=['junk']) util.exponential(operators=[test_paulistring, 'junk']) util.exponential( operators=[test_paulistring, test_paulisum, 'junk']) util.exponential(operators=[test_paulistring, test_paulisum]) # coefficients with self.assertRaisesRegex(TypeError, expected_regex='not a list'): util.exponential(operators=[], coefficients='junk') with self.assertRaisesRegex(TypeError, expected_regex='Each element'): util.exponential(operators=[test_paulistring], coefficients=[None]) util.exponential(operators=[test_paulistring, test_paulisum], coefficients=[1.0, None]) util.exponential( operators=[test_paulistring, test_paulisum, test_paulisum], coefficients=[1.0, 'test', sympy.Symbol('test')]) with self.assertRaisesRegex(ValueError, expected_regex='should be the same as'): util.exponential(operators=[test_paulistring], coefficients=[])