Skip to content

Commit 08d2a15

Browse files
committed
introduce labs fixes
1 parent be2826c commit 08d2a15

4 files changed

Lines changed: 37 additions & 11 deletions

File tree

qokit/portfolio_optimization.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ def get_data(N, seed=1, real=False) -> tuple[float, float]:
9393

9494
from qokit.yahoo import YahooDataProvider
9595

96-
random.seed(seed)
97-
9896
stock_symbols = [
9997
"AAPL",
10098
"GOOGL",
@@ -131,8 +129,7 @@ def get_data(N, seed=1, real=False) -> tuple[float, float]:
131129
]
132130

133131
data = YahooDataProvider(
134-
# tickers=stock_symbols[:N],
135-
tickers=random.sample(stock_symbols, N),
132+
tickers=stock_symbols[:N],
136133
start=datetime.datetime(2020, 1, 1),
137134
end=datetime.datetime(2020, 1, 30),
138135
)

qokit/qaoa_circuit.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ def append_z_prod_term(qc: QuantumCircuit, indices: Sequence, gamma: float) -> N
3232
qc.cx(indices[0], indices[1])
3333
elif term_weight == 2:
3434
qc.rzz(2 * gamma, indices[0], indices[1])
35+
elif term_weight == 1:
36+
qc.rz(2 * gamma, indices[0])
3537
else:
3638
# fallback to general case
3739
target = indices[-1]
@@ -56,7 +58,7 @@ def append_cost_operator_circuit(qc: QuantumCircuit, terms: Sequence, gamma: flo
5658
if len(term) == 2 and isinstance(term[1], Sequence):
5759
coeff, indices = term
5860
append_z_prod_term(qc, indices, gamma * coeff / 2)
59-
elif any([isinstance(i, tuple) for i in term]):
61+
elif any([isinstance(i, Sequence) for i in term]):
6062
raise ValueError(f"Invalid term received: {term}")
6163
else:
6264
append_z_prod_term(qc, term, gamma / 2)

tests/test_furxz_simulator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
from qokit.fur.diagonal_precomputation import precompute_vectorized_cpu_parallel
88
from qiskit_aer import AerSimulator
99
import pytest
10+
import os
1011
import sys
1112

13+
PYTHON_ONLY = False if os.environ.get("QOKIT_PYTHON_ONLY") is None else os.environ.get("QOKIT_PYTHON_ONLY")
1214

13-
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="Fast c/c++ simulator should be installed")
15+
@pytest.mark.skipif(PYTHON_ONLY, reason="Fast c/c++ simulator is not installed if PYTHON_ONLY is set")
1416
def test_furxz_backends():
1517

1618
N = 10
@@ -67,7 +69,6 @@ def test_ws_degeneracy():
6769
assert np.isclose(qiskit_energy, qaoa_energy)
6870

6971

70-
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="Fast c/c++ simulator should be installed")
7172
def test_qiskit_qokit():
7273
##### qiskit circuit
7374

@@ -80,7 +81,7 @@ def test_qiskit_qokit():
8081
gamma, beta = get_fixed_gamma_beta(d=d, p=p)
8182
ini_rots = np.random.rand(N)
8283

83-
simclass = qokit.fur.choose_simulator_xz(name="c")
84+
simclass = qokit.fur.choose_simulator_xz(name="python")
8485
sim = simclass(N, terms=terms)
8586
_result = sim.simulate_ws_qaoa(list(np.asarray(gamma)), list(np.asarray(beta)), ini_rots)
8687
qaoa_prob = sim.get_probabilities(_result)

tests/test_qaoa_qiskit.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@
55
import numpy as np
66
import pandas as pd
77
from qiskit_aer import AerSimulator
8+
from qiskit import transpile
89
from pathlib import Path
9-
from qokit.utils import precompute_energies, obj_from_statevector, get_ramp
10+
from qokit.utils import precompute_energies, obj_from_statevector, get_ramp, reverse_array_index_bit_order
1011
from qokit.qaoa_circuit_labs import (
1112
get_parameterized_qaoa_circuit,
1213
get_qaoa_circuit,
1314
)
14-
from qokit.labs import negative_merit_factor_from_bitstring
15+
from qokit.qaoa_circuit import get_qaoa_circuit_from_terms
16+
from qokit.labs import negative_merit_factor_from_bitstring, get_terms_offset
1517
from qokit.utils import (
1618
precompute_energies,
1719
obj_from_statevector,
1820
get_ramp,
1921
)
20-
22+
from qokit.fur.diagonal_precomputation import precompute_vectorized_cpu_parallel
2123
from qokit.qaoa_objective_labs import get_qaoa_labs_objective
24+
from qokit import parameter_utils
2225

2326
test_qaoa_qiskit_folder = Path(__file__).parent
2427

@@ -83,3 +86,26 @@ def test_parameterized_circuit():
8386

8487
assert np.isclose(f1, f2)
8588
assert np.isclose(f1, f3)
89+
90+
91+
def test_labs_circuit_from_terms_overlap():
92+
"""Test that building a LABS QAOA circuit via the general get_qaoa_circuit_from_terms
93+
and running it on Aer produces the expected overlap with optimal bitstrings."""
94+
N = 6
95+
p = 1
96+
97+
gamma, beta = parameter_utils.get_best_known_parameters_for_LABS_wrt_overlap_for_p(N, p)
98+
terms, offset = get_terms_offset(N)
99+
100+
qc = get_qaoa_circuit_from_terms(N, terms, gamma, beta)
101+
backend = AerSimulator(method="statevector")
102+
sv = reverse_array_index_bit_order(np.array(backend.run(transpile(qc, backend)).result().get_statevector()))
103+
104+
diag = precompute_vectorized_cpu_parallel(terms, offset, N)
105+
probs = np.abs(sv) ** 2
106+
overlap = probs[diag == diag.min()].sum()
107+
108+
# Cross-check against stored expected overlap
109+
params_df = parameter_utils.get_best_known_parameters_for_LABS_wrt_overlap(N)
110+
expected_overlap = params_df[params_df["p"] == p].squeeze()["overlap"]
111+
assert np.isclose(overlap, expected_overlap, atol=1e-4), f"overlap {overlap} != expected {expected_overlap}"

0 commit comments

Comments
 (0)