def test_imul_qubit_op(): op1 = QubitOperator(((0, 'Y'), (3, 'X'), (8, 'Z'), (11, 'X')), 3.j) op2 = QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 0.5) op1 *= op2 correct_term = ((0, 'Y'), (1, 'X'), (3, 'Z'), (11, 'X')) assert len(op1.terms) == 1 assert correct_term in op1.terms
def test_mul_multiple_terms(): operator = QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 0.5) operator += QubitOperator(((1, 'Z'), (3, 'X'), (8, 'Z')), 1.2) operator += QubitOperator(((1, 'Z'), (3, 'Y'), (9, 'Z')), 1.4j) res = operator * operator correct = QubitOperator((), 0.5**2 + 1.2**2 + 1.4j**2) correct += QubitOperator(((1, 'Y'), (3, 'Z')), 2j * 1j * 0.5 * 1.2) assert res == correct
def test_imul_qubit_op_2(): op3 = QubitOperator(((1, 'Y'), (0, 'X')), -1j) op4 = QubitOperator(((1, 'Y'), (0, 'X'), (2, 'Z')), -1.5) op3 *= op4 op4 *= op3 assert ((2, 'Z'), ) in op3.terms assert op3.terms[((2, 'Z'), )] == 1.5j assert op4.terms[((0, 'X'), (1, 'Y'))] == -2.25j
def test_get_operators(): """Tests get_operators() with an operator with two terms.""" operator_00 = QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 1) operator_01 = QubitOperator(((2, 'Z'), (3, 'Y')), 1) sum_operator = operator_00 + operator_01 operators = list(sum_operator.get_operators()) assert operators in [[operator_00, operator_01], [operator_01, operator_00]]
def test_mul_out_of_place(): op1 = QubitOperator(((0, 'Y'), (3, 'X'), (8, 'Z'), (11, 'X')), 3.j) op2 = QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 0.5) op3 = op1 * op2 correct_coefficient = 1.j * 3.0j * 0.5 correct_term = ((0, 'Y'), (1, 'X'), (3, 'Z'), (11, 'X')) assert op1 == QubitOperator(((0, 'Y'), (3, 'X'), (8, 'Z'), (11, 'X')), 3.j) assert op2 == QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 0.5) assert op3 == QubitOperator(correct_term, correct_coefficient)
def test_imul_bidir(): op_a = QubitOperator(((1, 'Y'), (0, 'X')), -1j) op_b = QubitOperator(((1, 'Y'), (0, 'X'), (2, 'Z')), -1.5) op_a *= op_b op_b *= op_a assert ((2, 'Z'), ) in op_a.terms assert op_a.terms[((2, 'Z'), )] == 1.5j assert ((0, 'X'), (1, 'Y')) in op_b.terms assert op_b.terms[((0, 'X'), (1, 'Y'))] == -2.25j
def test_renormalize(): operator = QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 1) operator += QubitOperator(((2, 'Z'), (3, 'Y')), 1) operator.renormalize() for term in operator.terms: assert operator.terms[term] == pytest.approx(1 / numpy.sqrt(2.)) assert operator.induced_norm(2) == pytest.approx(1.)
class TestTimeEvolutionOfHamiltonian: @pytest.fixture( params=[ PauliSum( [ PauliTerm("X", 0) * PauliTerm("X", 1), PauliTerm("Y", 0, 0.5) * PauliTerm("Y", 1), PauliTerm("Z", 0, 0.3) * PauliTerm("Z", 1), ] ), QubitOperator("[X0 X1] + 0.5[Y0 Y1] + 0.3[Z0 Z1]"), ] ) def hamiltonian(self, request): return request.param @pytest.mark.parametrize("time", [0.1]) # [0.1, 0.4, 1.0]) @pytest.mark.parametrize("order", [2]) # [1, 2, 3]) def test_evolution_with_numerical_time_produces_correct_result( self, hamiltonian, time, order ): cirq_qubits = cirq.LineQubit(0), cirq.LineQubit(1) expected_cirq_circuit = _cirq_exponentiate_hamiltonian( hamiltonian, cirq_qubits, time, order ) reference_unitary = cirq.unitary(expected_cirq_circuit) unitary = time_evolution(hamiltonian, time, trotter_order=order).to_unitary() assert compare_unitary(unitary, reference_unitary, tol=1e-10) @pytest.mark.parametrize("time_value", [0.1, 0.4, 1.0]) @pytest.mark.parametrize("order", [1, 2, 3]) def test_time_evolution_with_symbolic_time_produces_correct_unitary( self, hamiltonian, time_value, order ): time_symbol = sympy.Symbol("t") symbols_map = [(time_symbol, time_value)] cirq_qubits = cirq.LineQubit(0), cirq.LineQubit(1) expected_cirq_circuit = _cirq_exponentiate_hamiltonian( hamiltonian, cirq_qubits, time_value, order ) reference_unitary = cirq.unitary(expected_cirq_circuit) unitary = ( time_evolution(hamiltonian, time_symbol, trotter_order=order) .evaluate(symbols_map) .to_unitary() ) assert compare_unitary(unitary, reference_unitary, tol=1e-10)
class TestTimeEvolutionDerivatives: @pytest.fixture( params=[ PauliSum( [ PauliTerm("X", 0) * PauliTerm("X", 1), PauliTerm("Y", 0, 0.5) * PauliTerm("Y", 1), PauliTerm("Z", 0, 0.3) * PauliTerm("Z", 1), ] ), QubitOperator("[X0 X1] + 0.5[Y0 Y1] + 0.3[Z0 Z1]"), ] ) def hamiltonian(self, request): return request.param @pytest.mark.parametrize("time", [0.4, sympy.Symbol("t")]) def test_time_evolution_derivatives_gives_correct_number_of_derivatives_and_factors( self, time, hamiltonian ): order = 3 reference_factors_1 = [1.0 / order, 0.5 / order, 0.3 / order] * 3 reference_factors_2 = [-1.0 * x for x in reference_factors_1] derivatives, factors = time_evolution_derivatives( hamiltonian, time, trotter_order=order ) if isinstance(hamiltonian, QubitOperator): terms = list(hamiltonian.get_operators()) elif isinstance(hamiltonian, PauliSum): terms = hamiltonian.terms assert len(derivatives) == order * 2 * len(terms) assert len(factors) == order * 2 * len(terms) assert factors[0:18:2] == reference_factors_1 assert factors[1:18:2] == reference_factors_2
def generate_operator(begin, end): """Returns a sum of Z operators at qubit [begin, end).""" operator = QubitOperator.zero() for i in range(begin, end): operator += QubitOperator(((i, 'Z'), ), 1) return operator
* trotter_order ) @pytest.mark.parametrize( "term, time, expected_unitary", [ (PauliTerm("X", 0) * PauliTerm("X", 1), np.pi, -np.eye(4)), ( PauliTerm("Y", 0, 0.5) * PauliTerm("Y", 1), np.pi, np.diag([1j, -1j, -1j, 1j])[::-1], ), (PauliTerm("Z", 0) * PauliTerm("Z", 1), np.pi, -np.eye(4)), (PauliTerm("I", 0) * PauliTerm("I", 1), np.pi, -np.eye(2)), (QubitOperator("[X0 X1]"), np.pi, -np.eye(4)), ( QubitOperator("0.5 [Y0 Y1]"), np.pi, np.diag([1j, -1j, -1j, 1j])[::-1], ), (QubitOperator("[Z0 Z1]"), np.pi, -np.eye(4)), ], ) class TestTimeEvolutionOfTerm: def test_evolving_pauli_term_with_numerical_time_gives_correct_unitary( self, term, time, expected_unitary ): actual_unitary = time_evolution_for_term(term, time).to_unitary() np.testing.assert_array_almost_equal(actual_unitary, expected_unitary)
def test_mul_npfloat64(): operator = QubitOperator(((1, 'X'), (3, 'Y')), 0.5) res = operator * numpy.float64(0.5) assert res == QubitOperator(((1, 'X'), (3, 'Y')), 0.5 * 0.5)
def test_mul_bad_multiplier(): operator = QubitOperator(((1, 'Y'), (0, 'X')), -1j) with pytest.raises(TypeError): operator = operator * "0.5"
def test_different_indices_commute(): qubit_op = QubitOperator('X1') assert qubit_op.different_indices_commute is True
def test_imul_scalar(multiplier): loc_op = ((1, 'X'), (2, 'Y')) qubit_op = QubitOperator(loc_op) qubit_op *= multiplier assert qubit_op.terms[loc_op] == pytest.approx(multiplier)
def test_init_simplify(): assert QubitOperator("X0 X0") == QubitOperator.identity() assert QubitOperator("X1 X1") == QubitOperator.identity() assert QubitOperator("Y0 Y0") == QubitOperator.identity() assert QubitOperator("Z0 Z0") == QubitOperator.identity() assert QubitOperator("X0 Y0") == QubitOperator("Z0", coefficient=1j) assert QubitOperator("Y0 X0") == QubitOperator("Z0", coefficient=-1j) assert QubitOperator("X0 Y0 Z0") == 1j * QubitOperator.identity() assert QubitOperator("Y0 Z0 X0") == 1j * QubitOperator.identity() assert QubitOperator("Z0 Y0 X0") == -1j * QubitOperator.identity() assert QubitOperator("X1 Y0 X1") == QubitOperator("Y0") assert QubitOperator("Y1 Y1 Y1") == QubitOperator("Y1") assert QubitOperator("Y2 Y2 Y2 Y2") == QubitOperator.identity() assert QubitOperator("Y3 Y3 Y3 Y3 Y3") == QubitOperator("Y3") assert QubitOperator("Y4 Y4 Y4 Y4 Y4 Y4") == QubitOperator.identity() assert QubitOperator("X0 Y1 Y0 X1") == QubitOperator("Z0 Z1") assert QubitOperator("X0 Y1 Z3 X2 Z3 Y0") == QubitOperator("Z0 Y1 X2", coefficient=1j)
def test_imul_inplace(): qubit_op = QubitOperator("X1") prev_id = id(qubit_op) qubit_op *= 3. assert id(qubit_op) == prev_id
def check_sum(operators, operator): """Checks sum of operators matches to operator.""" return QubitOperator.accumulate(operators) == operator
def test_mul_by_scalarzero(): operator = QubitOperator(((1, 'Y'), (0, 'X')), -1j) * 0 assert ((0, 'X'), (1, 'Y')) in operator.terms assert operator.terms[((0, 'X'), (1, 'Y'))] == pytest.approx(0.0)
def test_get_operator_groups_empty(): """Tests get_operator_groups() with zero operator.""" operator = QubitOperator.zero() operators = list(operator.get_operator_groups(1)) assert operators == []
def test_renormalize_error(): operator = QubitOperator() with pytest.raises(ZeroDivisionError): operator.renormalize()
def test_get_operators_one(): """Tests get_operators() with an operator with a single term.""" operator = QubitOperator(((1, 'X'), (3, 'Y'), (8, 'Z')), 1) operators = list(operator.get_operators()) assert operators == [operator]