Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting symbols as parameters and add nsimplify to results #300

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion tangelo/linq/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
from typing import Union

from numpy import integer, ndarray, floating
from sympy import Symbol
ValentinS4t1qbit marked this conversation as resolved.
Show resolved Hide resolved


ONE_QUBIT_GATES = {"H", "X", "Y", "Z", "S", "T", "RX", "RY", "RZ", "PHASE"}
TWO_QUBIT_GATES = {"CNOT", "CX", "CY", "CZ", "CRX", "CRY", "CRZ", "CPHASE", "XX", "SWAP"}
Expand Down Expand Up @@ -172,7 +174,7 @@ def inverse(self):

if self.parameter == "":
new_parameter = ""
elif isinstance(self.parameter, (float, floating, int, integer)):
elif isinstance(self.parameter, (float, floating, int, integer, Symbol)):
new_parameter = -self.parameter
else:
raise AttributeError(f"{self.name} is not an invertible gate when parameter is {self.parameter}")
Expand Down
18 changes: 11 additions & 7 deletions tangelo/linq/target/target_sympy.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ def simulate_circuit(self, source_circuit: Circuit, return_statevector=False, in

frequencies = dict()
for vec, prob in measurements:
prob = simplify(prob, tolerance=1e-4)
bistring = "".join(str(bit) for bit in reversed(vec.qubit_values))
frequencies[bistring] = prob
prob = simplify(prob, tolerance=1e-4).evalf()
if not prob.is_zero:
bistring = "".join(str(bit) for bit in reversed(vec.qubit_values))
frequencies[bistring] = prob

return (frequencies, python_statevector) if return_statevector else (frequencies, None)

Expand All @@ -97,14 +98,17 @@ def expectation_value_from_prepared_state(self, qubit_operator, n_qubits, prepar
sympy.core.add.Add: Eigenvalue represented as a symbolic sum.
"""

from sympy import simplify
from sympy.physics.quantum import qapply, Dagger
from sympy import simplify, cos
from sympy.physics.quantum import Dagger

prepared_state = self._current_state if prepared_state is None else prepared_state
operator = translate_operator(qubit_operator, source="tangelo", target="sympy", n_qubits=n_qubits)
eigenvalue = qapply(Dagger(prepared_state) * operator * prepared_state)

return simplify(eigenvalue)
eigenvalue = Dagger(prepared_state) * operator * prepared_state
eigenvalue = eigenvalue[0, 0].rewrite(cos)
eigenvalue = simplify(eigenvalue).evalf()

return eigenvalue

@staticmethod
def backend_info():
Expand Down
2 changes: 1 addition & 1 deletion tangelo/linq/translator/translate_qubitop.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def translate_operator(qubit_operator, source, target, n_qubits=None):
if target in {"qiskit", "sympy"}:
# The count_qubits function has no way to detect the number of
# qubits when an operator is only a tensor product of I.
if qubit_operator == QubitOperator((), qubit_operator.constant):
if qubit_operator == QubitOperator((), qubit_operator.constant) and n_qubits is None:
alexfleury-sb marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError("The number of qubits (n_qubits) must be provided.")
n_qubits = count_qubits(qubit_operator) if n_qubits is None else n_qubits
qubit_operator = FROM_TANGELO[target](qubit_operator, n_qubits)
Expand Down
12 changes: 8 additions & 4 deletions tangelo/linq/translator/translate_sympy.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,19 @@ def translate_op_to_sympy(qubit_operator, n_qubits):
sympy.core.add.Add: Summation of sympy.physics.quantum.TensorProduct
objects.
"""
from sympy import Identity
from sympy.physics.paulialgebra import Pauli
from sympy import Matrix, I, zeros
from sympy.physics.quantum import TensorProduct

# Pauli string to sympy Pauli algebra objects.
map_to_paulis = {"I": Identity(1), "X": Pauli(1), "Y": Pauli(2), "Z": Pauli(3)}
map_to_paulis = {
ValentinS4t1qbit marked this conversation as resolved.
Show resolved Hide resolved
"I": Matrix([[1, 0], [0, 1]]),
"X": Matrix([[0, 1], [1, 0]]),
"Y": Matrix([[0, -I], [I, 0]]),
"Z": Matrix([[1, 0], [0, -1]])
}

# Contruct the TensorProduct objects.
sum_tensor_paulis = 0.
sum_tensor_paulis = zeros(2**n_qubits, 2**n_qubits)
for term_tuple, coeff in qubit_operator.terms.items():
term_string = pauli_of_to_string(term_tuple, n_qubits)
paulis = [map_to_paulis[p] for p in term_string[::-1]]
Expand Down