def test_permute_on_list_op(self): """Test if ListOp permute method is consistent with PrimitiveOps permute methods.""" op1 = (X ^ Y ^ Z).to_circuit_op() op2 = Z ^ X ^ Y # ComposedOp indices = [1, 2, 0] primitive_op = op1 @ op2 primitive_op_perm = primitive_op.permute(indices) # CircuitOp.permute composed_op = ComposedOp([op1, op2]) composed_op_perm = composed_op.permute(indices) # reduce the ListOp to PrimitiveOp to_primitive = composed_op_perm.oplist[0] @ composed_op_perm.oplist[1] # compare resulting PrimitiveOps equal = np.allclose(primitive_op_perm.to_matrix(), to_primitive.to_matrix()) self.assertTrue(equal) # TensoredOp indices = [3, 5, 4, 0, 2, 1] primitive_op = op1 ^ op2 primitive_op_perm = primitive_op.permute(indices) tensored_op = TensoredOp([op1, op2]) tensored_op_perm = tensored_op.permute(indices) # reduce the ListOp to PrimitiveOp composed_oplist = tensored_op_perm.oplist to_primitive = (composed_oplist[0] @ (composed_oplist[1].oplist[0] ^ composed_oplist[1].oplist[1]) @ composed_oplist[2]) # compare resulting PrimitiveOps equal = np.allclose(primitive_op_perm.to_matrix(), to_primitive.to_matrix()) self.assertTrue(equal) # SummedOp primitive_op = X ^ Y ^ Z summed_op = SummedOp([primitive_op]) indices = [1, 2, 0] primitive_op_perm = primitive_op.permute(indices) # PauliOp.permute summed_op_perm = summed_op.permute(indices) # reduce the ListOp to PrimitiveOp to_primitive = summed_op_perm.oplist[ 0] @ primitive_op @ summed_op_perm.oplist[2] # compare resulting PrimitiveOps equal = np.allclose(primitive_op_perm.to_matrix(), to_primitive.to_matrix()) self.assertTrue(equal)
def test_empty_listops(self): """Test reduce and eval on ListOp with empty oplist.""" with self.subTest("reduce empty ComposedOp "): self.assertEqual(ComposedOp([]).reduce(), ComposedOp([])) with self.subTest("reduce empty TensoredOp "): self.assertEqual(TensoredOp([]).reduce(), TensoredOp([])) with self.subTest("eval empty ComposedOp "): self.assertEqual(ComposedOp([]).eval(), 0.0) with self.subTest("eval empty TensoredOp "): self.assertEqual(TensoredOp([]).eval(), 0.0)
def test_expand_on_list_op(self): """ Test if expanded ListOp has expected num_qubits. """ add_qubits = 3 # ComposedOp composed_op = ComposedOp([(X ^ Y ^ Z), (H ^ T), (Z ^ X ^ Y ^ Z).to_matrix_op()]) expanded = composed_op._expand_dim(add_qubits) self.assertEqual(composed_op.num_qubits + add_qubits, expanded.num_qubits) # TensoredOp tensored_op = TensoredOp([(X ^ Y), (Z ^ I)]) expanded = tensored_op._expand_dim(add_qubits) self.assertEqual(tensored_op.num_qubits + add_qubits, expanded.num_qubits) # SummedOp summed_op = SummedOp([(X ^ Y), (Z ^ I ^ Z)]) expanded = summed_op._expand_dim(add_qubits) self.assertEqual(summed_op.num_qubits + add_qubits, expanded.num_qubits)
def test_compose_consistency(self): """Test if PrimitiveOp @ ComposedOp is consistent with ComposedOp @ PrimitiveOp.""" # PauliOp op1 = X ^ Y ^ Z op2 = X ^ Y ^ Z op3 = (X ^ Y ^ Z).to_circuit_op() comp1 = op1 @ ComposedOp([op2, op3]) comp2 = ComposedOp([op3, op2]) @ op1 self.assertListEqual(comp1.oplist, list(reversed(comp2.oplist))) # CircitOp op1 = op1.to_circuit_op() op2 = op2.to_circuit_op() op3 = op3.to_matrix_op() comp1 = op1 @ ComposedOp([op2, op3]) comp2 = ComposedOp([op3, op2]) @ op1 self.assertListEqual(comp1.oplist, list(reversed(comp2.oplist))) # MatrixOp op1 = op1.to_matrix_op() op2 = op2.to_matrix_op() op3 = op3.to_pauli_op() comp1 = op1 @ ComposedOp([op2, op3]) comp2 = ComposedOp([op3, op2]) @ op1 self.assertListEqual(comp1.oplist, list(reversed(comp2.oplist)))
def test_coder_operators(self): """Test runtime encoder and decoder for operators.""" x = Parameter("x") y = x + 1 qc = QuantumCircuit(1) qc.h(0) coeffs = np.array([1, 2, 3, 4, 5, 6]) table = PauliTable.from_labels( ["III", "IXI", "IYY", "YIZ", "XYZ", "III"]) op = (2.0 * I ^ I) z2_symmetries = Z2Symmetries( [Pauli("IIZI"), Pauli("ZIII")], [Pauli("IIXI"), Pauli("XIII")], [1, 3], [-1, 1]) isqrt2 = 1 / np.sqrt(2) sparse = scipy.sparse.csr_matrix([[0, isqrt2, 0, isqrt2]]) subtests = ( PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), coeff=3), PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1]), coeff=y), PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1 + 2j]), coeff=3 - 2j), PauliSumOp.from_list([("II", -1.052373245772859), ("IZ", 0.39793742484318045)]), PauliSumOp(SparsePauliOp(table, coeffs), coeff=10), MatrixOp(primitive=np.array([[0, -1j], [1j, 0]]), coeff=x), PauliOp(primitive=Pauli("Y"), coeff=x), CircuitOp(qc, coeff=x), EvolvedOp(op, coeff=x), TaperedPauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), z2_symmetries), StateFn(qc, coeff=x), CircuitStateFn(qc, is_measurement=True), DictStateFn("1" * 3, is_measurement=True), VectorStateFn(np.ones(2**3, dtype=complex)), OperatorStateFn(CircuitOp(QuantumCircuit(1))), SparseVectorStateFn(sparse), Statevector([1, 0]), CVaRMeasurement(Z, 0.2), ComposedOp([(X ^ Y ^ Z), (Z ^ X ^ Y ^ Z).to_matrix_op()]), SummedOp([X ^ X * 2, Y ^ Y], 2), TensoredOp([(X ^ Y), (Z ^ I)]), (Z ^ Z) ^ (I ^ 2), ) for op in subtests: with self.subTest(op=op): encoded = json.dumps(op, cls=RuntimeEncoder) self.assertIsInstance(encoded, str) decoded = json.loads(encoded, cls=RuntimeDecoder) self.assertEqual(op, decoded)
def test_composed_op_immutable_under_eval(self): """Test ``ComposedOp.eval`` does not change the operator instance.""" op = 2 * ComposedOp([X]) _ = op.eval() # previous bug: after op.eval(), op was 2 * ComposedOp([2 * X]) self.assertEqual(op, 2 * ComposedOp([X]))