Skip to content

Commit

Permalink
Fix incorrect decoding of decision variables by MagicRounding (#627
Browse files Browse the repository at this point in the history
…) (#633)

* Minor fixes

* Add files via upload

* Add files via upload

* simplify iterator expression

Co-authored-by: Takashi Imamichi <[email protected]>

* modify releasenotes

Co-authored-by: Takashi Imamichi <[email protected]>

---------

Co-authored-by: Takashi Imamichi <[email protected]>
(cherry picked from commit 807d481)

Co-authored-by: Yuki Sato <[email protected]>
  • Loading branch information
mergify[bot] and yksat authored Aug 9, 2024
1 parent d789ccc commit a3646c8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
2 changes: 1 addition & 1 deletion qiskit_optimization/algorithms/qrao/magic_rounding.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def _unpack_measurement_outcome(
"""
output_bits = []
# iterate in order over decision variables
for q, op in var2op.values():
for _, (q, op) in sorted(var2op.items()):
# get the decoding outcome index for the variable
# corresponding to this Pauli op.
op_index = self._OP_INDICES[vars_per_qubit][str(op.paulis[0])]
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/fix-qrao-d0402da6a5c40121.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
fixes:
- |
Fixed a bug of :meth:`.MagicRounding.round` that may return a wrong decision variable order.
24 changes: 24 additions & 0 deletions test/algorithms/qrao/test_magic_rounding.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import unittest
from test.optimization_test_case import QiskitOptimizationTestCase

import networkx as nx
import numpy as np
from qiskit.circuit import QuantumCircuit
from qiskit.primitives import Sampler
Expand All @@ -27,6 +28,7 @@
RoundingContext,
RoundingResult,
)
from qiskit_optimization.applications import Maxcut
from qiskit_optimization.problems import QuadraticProgram


Expand All @@ -42,6 +44,15 @@ def setUp(self):
self.problem.binary_var("z")
self.problem.minimize(linear={"x": 1, "y": 2, "z": 3})

# trivial maxcut problem (solution: {1}, {0, 2} with cut val 2)
graph = nx.Graph()
graph.add_nodes_from([0, 1, 2])
graph.add_edges_from([(0, 1), (1, 2)])
maxcut = Maxcut(graph)
self.maxcut_problem = maxcut.to_quadratic_program()
self.maxcut_optimal_value = 2.0
self.maxcut_optimal_solution = [0, 1, 0]

def test_magic_rounding_constructor(self):
"""Test constructor"""
sampler = Sampler(options={"shots": 10000, "seed": 42})
Expand Down Expand Up @@ -287,6 +298,19 @@ def test_magic_rounding_round_weighted_3_1_qrac(self):
[0.2672612419124245, 0.5345224838248487, 0.8017837257372733],
)

def test_mapping_magic_rounding_result(self):
"""Test the mapping of magic rounding result bits to variables"""
encoding = QuantumRandomAccessEncoding(max_vars_per_qubit=1)
encoding.encode(self.maxcut_problem)
circuit = encoding.state_preparation_circuit(self.maxcut_optimal_solution)
rounding_context = RoundingContext(encoding=encoding, expectation_values=0, circuit=circuit)
sampler = Sampler(options={"shots": 1})
magic_rounding = MagicRounding(sampler=sampler)
rounding_result = magic_rounding.round(rounding_context)
solution = rounding_result.samples[0]
self.assertEqual(solution.fval, self.maxcut_optimal_value)
np.testing.assert_allclose(solution.x, self.maxcut_optimal_solution)

def test_magic_rounding_exceptions(self):
"""Test exceptions in the MagicRounding class"""
encoding = QuantumRandomAccessEncoding(max_vars_per_qubit=3)
Expand Down

0 comments on commit a3646c8

Please sign in to comment.