Skip to content

Commit

Permalink
Removing redundant functions
Browse files Browse the repository at this point in the history
  • Loading branch information
vinitha-balachandran committed Apr 26, 2024
1 parent 1c0ed63 commit 79f9f76
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 33 deletions.
36 changes: 3 additions & 33 deletions src/qibotn/eval_qu.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ def expectation_qu(
# use cotengra package for tensor contractions
import cotengra as ctg

# used to add one more qubit to the circuit to make the observable local
qasm_mod, nqubits = modify_qasm(qasm)
nqubits = int(np.log2(len(initial_state)))

if initial_state is not None:
initial_state = init_state_tn(nqubits, initial_state)
Expand All @@ -77,7 +76,7 @@ def expectation_qu(
)

# generates the global observable
obs = pauli_string_gen(nqubits - 1, pauli_string_pattern)
obs = pauli_string_gen(nqubits, pauli_string_pattern)

# parameters to find the contraction path using cotengra
opt = ctg.ReusableHyperOptimizer(
Expand All @@ -99,41 +98,12 @@ def expectation_qu(

# expectation value
expectation = circ_quimb.local_expectation(
obs, where=list(range(nqubits - 1)), optimize=opt, simplify_sequence="DRC"
obs, where=list(range(nqubits)), optimize=opt, simplify_sequence="DRC"
)

return expectation


def modify_qasm(qasm_circ):
"""Generate a modified qasm string.
Args:
qasm (str): QASM program.
Returns:
string: QASM program with an additional auxillary qubit for the calculation of expectation
"""

import re

lines = qasm_circ.split("\n")

qasm_circ_mod = []
while lines:
line = lines.pop(0).strip()
sta = re.compile(r"qreg\s+(\w+)\s*\[(\d+)\];")
match = sta.match(line)
if match:
name, nqubits = match.groups()
qasm_circ_mod.append(f"qreg q[{int(nqubits)+1}];")
else:
qasm_circ_mod.append(line)
qasm_circ_mod = "\n".join(qasm_circ_mod)

return qasm_circ_mod, int(nqubits) + 1


def pauli_string_gen(nqubits, pauli_string_pattern):
"""Used internally to generate the string based on given pattern and number
of qubit.
Expand Down
68 changes: 68 additions & 0 deletions tests/test_quimb_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,71 @@ def test_eval(nqubits: int, tolerance: float, is_mps: bool):
assert np.allclose(
result_sv, result_tn, atol=tolerance
), "Resulting dense vectors do not match"


@pytest.mark.parametrize(
"nqubits, tolerance, is_mps",
[(1, 1e-6, True), (2, 1e-6, False), (5, 1e-3, True), (10, 1e-3, False)],
)
def test_eval_expectation(nqubits: int, tolerance: float, is_mps: bool):
"""Evaluate circuit with Quimb backend and calculate the expecatation value
of the given Pauli string.
Args:
nqubits (int): Total number of qubits in the system.
tolerance (float): Maximum limit allowed for difference in results
is_mps (bool): True if state is MPS and False for tensor network structure
"""
# hack quimb to use the correct number of processes
# TODO: remove completely, or at least delegate to the backend
# implementation
os.environ["QUIMB_NUM_PROCS"] = str(os.cpu_count())
import qibotn.eval_qu

init_state = create_init_state(nqubits=nqubits)
init_state_tn = copy.deepcopy(init_state)

# Test qibo
from qibo.hamiltonians import SymbolicHamiltonian
from qibo.symbols import X, Y

qibo.set_backend(backend=config.qibo.backend, platform=config.qibo.platform)
qibo_circ, state_vec = qibo_qft(nqubits, init_state, swaps=True)

# creating the Pauli string observable

list_of_objects = []
for i in range(nqubits):
if i % 4 == 0:
list_of_objects.append(X(i))
elif i % 4 == 1:
list_of_objects.append(X(i))
elif i % 4 == 2:
list_of_objects.append(X(i))
else:
list_of_objects.append(Y(i))
obs = np.prod(list_of_objects)
obs = SymbolicHamiltonian(obs)

# Noise-free expected value
qibo_exp = obs.expectation(state_vec)

# Convert to qasm for other backends
qasm_circ = qibo_circ.to_qasm()

# Test quimb
if is_mps:
gate_opt = {}
gate_opt["method"] = "svd"
gate_opt["cutoff"] = 1e-6
gate_opt["cutoff_mode"] = "abs"
else:
gate_opt = None

qibotn_exp = qibotn.eval_qu.expectation_qu(
qasm_circ, "XXXY", init_state_tn, gate_opt, backend=config.quimb.backend
)

assert np.allclose(
qibo_exp, qibotn_exp, atol=tolerance
), "Resulting dense vectors do not match"

0 comments on commit 79f9f76

Please sign in to comment.