Skip to content
Open
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
32 changes: 31 additions & 1 deletion tensorcircuit/compiler/qiskit_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
compiler interface via qiskit
"""

import ast
import re
from typing import Any, Dict, Optional

Expand All @@ -10,6 +11,35 @@
from ..translation import qiskit_from_qasm_str_ordered_measure, get_qiskit_qasm


def _safe_eval(s: str) -> Any:
operators = {
ast.Add: lambda a, b: a + b,
ast.Sub: lambda a, b: a - b,
ast.Mult: lambda a, b: a * b,
ast.Div: lambda a, b: a / b,
ast.Pow: lambda a, b: a ** b,
ast.USub: lambda a: -a,
ast.UAdd: lambda a: a,
}

def _eval(node: Any) -> Any:
if isinstance(node, ast.Expression):
return _eval(node.body)
if isinstance(node, ast.Constant):
return node.value
if isinstance(node, ast.Num): # python < 3.8
return node.n
if isinstance(node, ast.BinOp):
return operators[type(node.op)](_eval(node.left), _eval(node.right))
if isinstance(node, ast.UnaryOp):
return operators[type(node.op)](_eval(node.operand))
if isinstance(node, ast.Tuple):
return tuple(_eval(n) for n in node.elts)
raise ValueError(f"Unsupported node type: {type(node)}")

return _eval(ast.parse(s, mode="eval"))


def _free_pi(s: str) -> str:
# dirty trick to get rid of pi in openqasm from qiskit
rs = []
Expand All @@ -21,7 +51,7 @@ def _free_pi(s: str) -> str:
rs.append(r)
else:
v = r[inc.start() : inc.end()]
v = eval(v)
v = _safe_eval(v)
if not isinstance(v, tuple):
r = r[: inc.start()] + "(" + str(v) + ")" + r[inc.end() :]
else: # u gate case
Expand Down
Loading