Skip to content

Commit 20260d6

Browse files
Copilotfgfuchs
andauthored
Comprehensive tests, version bump, bug fixes, and repo consistency (#45)
* feat: upgrade to qiskit 2.3.0 - update imports, fix bugs, add tests Co-authored-by: fgfuchs <2428162+fgfuchs@users.noreply.github.com> * feat: comprehensive tests, version bump, bug fixes, and repo consistency improvements Co-authored-by: fgfuchs <2428162+fgfuchs@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: fgfuchs <2428162+fgfuchs@users.noreply.github.com>
1 parent 9e91d70 commit 20260d6

14 files changed

+1558
-25
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ This library already contains several standard implementations.
4040
- The following [problem](qaoa/problems/base_problem.py) cases are already available:
4141
- [Max k-CUT binary power of two](qaoa/problems/maxkcut_binary_powertwo.py) *
4242
- [Max k-CUT binary full H](qaoa/problems/maxkcut_binary_fullH.py)
43-
- [Max k-CUT binary one hot](qaoa/problems/maxkcut_binary_one_hot.py)
43+
- [Max k-CUT binary one hot](qaoa/problems/maxkcut_one_hot_problem.py)
4444
- [QUBO](qaoa/problems/qubo_problem.py)
4545
- [Exact cover](qaoa/problems/exactcover_problem.py)
4646
- [Portfolio](qaoa/problems/portfolio_problem.py)
@@ -66,12 +66,12 @@ It is **very easy to extend this list** by providing an implementation of a cir
6666
To make an ansatz for the MaxCut problem, the X-mixer and the initial state $|+\rangle^{\otimes n}$ one can create an instance like this:
6767

6868
qaoa = QAOA(
69-
initialstate=initialstates.Plus(),
7069
problem=problems.MaxKCutBinaryPowerOfTwo(G="some networkx instance", k_cuts=2),
71-
mixer=mixers.X()
70+
mixer=mixers.X(),
71+
initialstate=initialstates.Plus()
7272
)
7373

74-
*(can be used for the standard MaxCut with argument k_cuts=2)
74+
*(can be used for the standard MaxCut with argument k_cuts=2, or use `problems.MaxCut(G)` for convenience)*
7575
***
7676
### Run optimization at depth $p$
7777

@@ -106,7 +106,7 @@ QAOA supports the following keywords:
106106
cvar=
107107
)
108108

109-
- `backend`: the backend to be used, defaults to `Aer.get_backend("qasm_simulator")`
109+
- `backend`: the backend to be used, defaults to `AerSimulator()` (from `qiskit_aer`)
110110
- `noisemodel`: the noise model to be used, default to `None`,
111111
- `optimizer`: a list of the optimizer to be used from qiskit-algorithms together with options, defaults to `[COBYLA, {}]`,
112112
- `precision`: sampel until a certain precision of the expectation value is reached based on $\text{error}=\frac{\text{variance}}{\sqrt{\text{shots}}}$, defaults to `None`,
@@ -136,9 +136,9 @@ Multi-angle QAOA allows components to use multiple parameters per layer, increas
136136
- **Parameterized initial state** (`PlusParameterized`): The initial state |+⟩ with optimizable per-qubit phase rotations
137137

138138
qaoa = QAOA(
139-
initialstate=initialstates.Plus(),
140139
problem=problems.MaxKCutBinaryPowerOfTwo(G="some networkx instance", k_cuts=2),
141-
mixer=mixers.XMultiAngle() # N_qubits beta parameters per layer
140+
mixer=mixers.XMultiAngle(), # N_qubits beta parameters per layer
141+
initialstate=initialstates.Plus()
142142
)
143143

144144
The flat angle array format used by `hist()`, `getParametersToBind()`, and `interp()` is:

qaoa/mixers/grover_mixer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, subcircuit: InitialState) -> None:
3232
self.mixer_param = Parameter("x_beta")
3333

3434
def create_circuit(self):
35-
"""
35+
r"""
3636
Constructs the Grover mixer circuit using the subcircuit.
3737
3838
Given feasible states f \in F,

qaoa/mixers/maxkcut_grover_mixer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ def create_circuit(self) -> None:
130130
tensor_feas = Tensor(circ_one_node, self.num_V)
131131

132132
gm = Grover(tensor_feas)
133+
gm.setNumQubits(tensor_feas.N_qubits)
133134

134135
gm.create_circuit()
135136
self.circuit = gm.circuit

qaoa/mixers/xy_mixer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def create_circuit(self):
5656

5757
@staticmethod
5858
def generate_pairs(n, case="ring"):
59-
"""_summary_
59+
"""Generates pairs of adjacent qubit indices for the given topology.
6060
6161
Args:
6262
n (int): The number of qubits.

qaoa/problems/portfolio_problem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ def cost_nonQUBO(self, string, penalize=True):
7575
# penalty = self.params.get("penalty", 0.0)
7676

7777
x = np.array(list(map(int, string)))
78-
cost = risk * (x.T @ cov_matrix @ x) - exp_return.T @ x
78+
cost = self.risk * (x.T @ self.cov_matrix @ x) - self.exp_return.T @ x
7979
if penalize:
80-
cost += penalty * (x.sum() - budget) ** 2
80+
cost += self.penalty * (x.sum() - self.budget) ** 2
8181

8282
return -cost
8383

qaoa/problems/qubo_problem.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@ class QUBO(Problem):
3030
createParameterizedCostCircuitTril(): Creates a parameterized circuit of the triangularized QUBO problem.
3131
"""
3232
def __init__(self, Q=None, c=None, b=None) -> None:
33-
super().__init__()
3433
"""
3534
Implements the mapping from the parameters in params to the QUBO problem.
3635
Is expected to be called by the child class.
3736
38-
# The QUBO will be on this form:
39-
# min x^T Q x + c^T x + b
37+
The QUBO will be on this form: min x^T Q x + c^T x + b
4038
4139
Args:
4240
Q (np.ndarray): A 2-dimensional numpy ndarray representing the quadratic coefficients.
@@ -48,6 +46,7 @@ def __init__(self, Q=None, c=None, b=None) -> None:
4846
AssertionError: If c is not a 1D numpy ndarray of compatible size.
4947
AssertionError: If b is not a scalar.
5048
"""
49+
super().__init__()
5150
assert type(Q) is np.ndarray, "Q needs to be a numpy ndarray, but is " + str(
5251
type(Q)
5352
)

qaoa/qaoa.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
)
1414
from qiskit.circuit import Parameter
1515
try:
16-
from qiskit.primitives import Sampler
16+
from qiskit_aer.primitives import SamplerV2 as _SamplerV2
1717
except ImportError:
18-
from qiskit_aer.primitives import Sampler
18+
from qiskit.primitives import StatevectorSampler as _SamplerV2
1919
from qiskit_algorithms.optimizers import COBYLA
2020

21-
from qiskit_aer import Aer
21+
from qiskit_aer import AerSimulator, Aer
2222

2323
from qaoa.initialstates import InitialState
2424
from qaoa.mixers import Mixer
@@ -198,7 +198,7 @@ def __init__(
198198
problem,
199199
mixer,
200200
initialstate,
201-
backend=Aer.get_backend("qasm_simulator"),
201+
backend=AerSimulator(),
202202
noisemodel=None,
203203
optimizer=[COBYLA, {}], # optimizer, options
204204
precision=None,
@@ -869,7 +869,7 @@ def local_opt(self, angles0):
869869
except TypeError as e: ### QNSPSA needs fidelity
870870
self.isQNSPSA = True
871871
self.optimizer[1]["fidelity"] = self.optimizer[0].get_fidelity(
872-
self.parameterized_circuit, sampler=Sampler()
872+
self.parameterized_circuit, sampler=_SamplerV2()
873873
)
874874
opt = self.optimizer[0](**self.optimizer[1])
875875
res = opt.minimize(self.loss, x0=angles0)

setup.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="qaoa",
5-
version="1.2.1",
5+
version="1.2.2",
66
license="GNU General Public License v3.0",
77
author="Franz Georg Fuchs",
88
author_email="franzgeorgfuchs@gmail.com",
@@ -11,17 +11,25 @@
1111
long_description_content_type="text/markdown",
1212
packages=find_packages(exclude=["examples", "images"]),
1313
keywords="quantum computing, qaoa, qiskit",
14+
python_requires=">=3.9",
1415
install_requires=[
1516
"numpy",
1617
"scipy",
1718
"structlog",
1819
"matplotlib",
1920
"networkx",
2021
"jupyter",
21-
"qiskit==1.1.1",
22-
"qiskit-aer",
23-
"qiskit-algorithms",
22+
"qiskit>=2.3.0",
23+
"qiskit-aer>=0.17.0",
24+
"qiskit-algorithms>=0.4.0",
2425
"qiskit-finance",
2526
"pylatexenc",
2627
],
28+
extras_require={
29+
"dev": [
30+
"twine>=6.0.0",
31+
"build>=1.0.0",
32+
"pytest>=7.0.0",
33+
],
34+
},
2735
)

0 commit comments

Comments
 (0)