Skip to content

Commit e41a472

Browse files
authored
Add custom ansatz op to state vector evaluator (#29)
2 parents bcd99b8 + d7cfe91 commit e41a472

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ This repository is still in development: new functionality is being added and th
171171
| 11 | Bug fix in train pre-processing data | #24 |
172172
| 12 | More data in result saving in train.py | #26 |
173173
| 13 | Create PPEvaluator from configs | #25 |
174+
| 14 | Custom ansatz operator to state vector | #29 |
174175

175176
## IBM Public Repository Disclosure
176177

qaoa_training_pipeline/evaluation/statevector_evaluator.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
"""Statevector-based QAOA evaluator."""
1010

11-
from typing import Dict, List, Optional
11+
from typing import Dict, List, Optional, Union
1212

1313
from qiskit import QuantumCircuit
1414
from qiskit.circuit.library import qaoa_ansatz
@@ -43,7 +43,7 @@ def evaluate(
4343
params: List[float],
4444
mixer: Optional[QuantumCircuit] = None,
4545
initial_state: Optional[QuantumCircuit] = None,
46-
ansatz_circuit: Optional[QuantumCircuit] = None,
46+
ansatz_circuit: Optional[Union[QuantumCircuit, SparsePauliOp]] = None,
4747
) -> float:
4848
"""Evaluate the expectation value of a cost operator given a set of parameters.
4949
@@ -56,16 +56,27 @@ def evaluate(
5656
initial_state (Optional[QuantumCircuit], optional): the initial state of the QAOA.
5757
"""
5858

59-
if ansatz_circuit is not None:
60-
raise NotImplementedError("Custom ansatz circuits are not yet supported.")
59+
if isinstance(ansatz_circuit, SparsePauliOp):
60+
ansatz_op = ansatz_circuit
61+
elif ansatz_circuit is None:
62+
ansatz_op = cost_op
63+
else:
64+
raise NotImplementedError(
65+
"Custom ansatz circuits in format"
66+
f"{ansatz_circuit.__class__.__name__} are not yet supported."
67+
)
6168

6269
circuit = qaoa_ansatz(
63-
cost_op,
70+
ansatz_op,
6471
reps=len(params) // 2,
6572
mixer_operator=mixer,
6673
initial_state=initial_state,
6774
)
6875

76+
# Prevents the edge case where the cost op is the identity.
77+
if len(circuit.parameters) != len(params):
78+
raise ValueError("The QAOA Circuit does not have the correct number of parameters. ")
79+
6980
result = self.primitive.run([(circuit, cost_op, params)]).result()
7081

7182
return float(result[0].data.evs)

qaoa_training_pipeline/training/param_result.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def __init__(
4747
"system": platform.system(),
4848
"processor": platform.processor(),
4949
"platform": platform.platform(),
50-
"qaoa_training_pipeline_version": 13,
50+
"qaoa_training_pipeline_version": 14,
5151
}
5252

5353
# Convert, e.g., np.float to float

test/evaluation/test_statevector.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,19 @@ def test_optimize(self):
4848
result = trainer.train(cost_op=self.cost_op, params0=[0.2, 0.3])
4949

5050
self.assertGreaterEqual(len(result["energy_history"]), 3)
51+
52+
def test_custom_ansatz(self):
53+
"""Test that we can construct the ansatz from a different operator."""
54+
ansatz_op = SparsePauliOp.from_list([("ZI", 1)])
55+
56+
angles = [1.2, 1.3]
57+
58+
energy1 = self.evaluator.evaluate(self.cost_op, params=angles, ansatz_circuit=ansatz_op)
59+
energy2 = self.evaluator.evaluate(self.cost_op, params=angles)
60+
61+
self.assertTrue(abs(energy1 - energy2) > 0.1)
62+
63+
energy1 = self.evaluator.evaluate(self.cost_op, params=angles, ansatz_circuit=self.cost_op)
64+
energy2 = self.evaluator.evaluate(self.cost_op, params=angles)
65+
66+
self.assertAlmostEqual(energy1, energy2, places=6)

0 commit comments

Comments
 (0)