Skip to content

Commit 27b4515

Browse files
authored
Merge pull request #65 from Jij-Inc/hotfix/decode
Fix interpretation of bit order
2 parents 0385560 + e262c37 commit 27b4515

File tree

4 files changed

+130
-9
lines changed

4 files changed

+130
-9
lines changed

qamomile/core/bitssample.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def from_int_counts(
8282
bitarrays = []
8383
for int_value, count in int_counts.items():
8484
# Convert the integer to a bit array of the specified length
85-
bitarray = list(map(int, bin(int_value)[2:].zfill(bit_length)))
85+
bitarray = list(map(int, bin(int_value)[2:].zfill(bit_length)[::-1]))
8686
bitarrays.append(BitsSample(count, bitarray))
8787
return cls(bitarrays)
8888

tests/qiskit/test_transpiler.py

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,59 @@
22

33
import pytest
44
import numpy as np
5+
import jijmodeling as jm
6+
import jijmodeling_transpiler.core as jmt
7+
import networkx as nx
58
import qiskit
69
import qiskit.quantum_info as qk_ope
10+
import qiskit.primitives as qk_pr
711
from qamomile.core.circuit import QuantumCircuit as QamomileCircuit
812
from qamomile.core.circuit import Parameter
913
from qamomile.core.operator import Hamiltonian, PauliOperator, Pauli
1014
import qamomile.core.bitssample as qm_bs
15+
16+
import qamomile.core as qm
1117
from qamomile.qiskit.transpiler import QiskitTranspiler
1218
from qamomile.qiskit.exceptions import QamomileQiskitTranspileError
1319

20+
def graph_coloring_problem() -> jm.Problem:
21+
# define variables
22+
V = jm.Placeholder("V")
23+
E = jm.Placeholder("E", ndim=2)
24+
N = jm.Placeholder("N")
25+
x = jm.BinaryVar("x", shape=(V, N))
26+
n = jm.Element("i", belong_to=(0, N))
27+
v = jm.Element("v", belong_to=(0, V))
28+
e = jm.Element("e", belong_to=E)
29+
# set problem
30+
problem = jm.Problem("Graph Coloring")
31+
# set one-hot constraint that each vertex has only one color
32+
33+
#problem += jm.Constraint("one-color", x[v, :].sum() == 1, forall=v)
34+
problem += jm.Constraint("one-color", jm.sum(n, x[v, n]) == 1, forall=v)
35+
# set objective function: minimize edges whose vertices connected by edges are the same color
36+
problem += jm.sum([n, e], x[e[0], n] * x[e[1], n])
37+
return problem
38+
39+
def graph_coloring_instance():
40+
G = nx.Graph()
41+
G.add_nodes_from([0, 1, 2, 3])
42+
G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 3)])
43+
E = [list(edge) for edge in G.edges]
44+
num_color = 3
45+
num_nodes = G.number_of_nodes()
46+
instance_data = {"V": num_nodes, "N": num_color, "E": E}
47+
return instance_data
48+
49+
def create_graph_coloring_operator_ansatz_initial_state(
50+
compiled_instance: jmt.CompiledInstance, num_nodes: int, num_color: int
51+
):
52+
n = num_color * num_nodes
53+
qc = QamomileCircuit(n)
54+
var_map = compiled_instance.var_map.var_map["x"]
55+
for i in range(num_nodes):
56+
qc.x(var_map[(i, 0)]) # set all nodes to color 0
57+
return qc
1458

1559
@pytest.fixture
1660
def transpiler():
@@ -111,7 +155,24 @@ def test_transpile_hamiltonian(transpiler):
111155
assert np.all(qiskit_hamiltonian.paulis == ['X'])
112156

113157

114-
115-
116-
117-
158+
def test_coloring_sample_decode():
159+
problem = graph_coloring_problem()
160+
instance_data = graph_coloring_instance()
161+
compiled_instance = jmt.compile_model(problem, instance_data)
162+
initial_circuit = create_graph_coloring_operator_ansatz_initial_state(compiled_instance, instance_data['V'], instance_data['N'])
163+
qaoa_converter = qm.qaoa.QAOAConverter(compiled_instance)
164+
qaoa_converter.ising_encode(multipliers={"one-color": 1})
165+
166+
qk_transpiler = QiskitTranspiler()
167+
sampler = qk_pr.StatevectorSampler()
168+
qk_circ = qk_transpiler.transpile_circuit(initial_circuit)
169+
qk_circ.measure_all()
170+
job = sampler.run([qk_circ])
171+
172+
job_result = job.result()
173+
174+
sampleset = qaoa_converter.decode(qk_transpiler, job_result[0].data['meas'])
175+
assert sampleset[0].var_values["x"].values == {(0, 0): 1, (1, 0): 1, (2, 0): 1, (3, 0): 1}
176+
assert sampleset[0].num_occurrences == 1024
177+
178+

tests/quri_parts/test_quri_transpiler.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,57 @@
11
import pytest
22
import numpy as np
3+
import networkx as nx
34
import collections
5+
import jijmodeling as jm
6+
import jijmodeling_transpiler.core as jmt
47
import quri_parts.circuit as qp_c
58
import quri_parts.core.operator as qp_o
9+
from quri_parts.qulacs.sampler import create_qulacs_vector_sampler
610
import qamomile.core.circuit as qm_c
711
import qamomile.core.operator as qm_o
812
import qamomile.core.bitssample as qm_bs
13+
import qamomile.core as qm
914
from qamomile.core.converters.qaoa import QAOAConverter
1015
from qamomile.quri_parts.transpiler import QuriPartsTranspiler
1116

12-
17+
def graph_coloring_problem() -> jm.Problem:
18+
# define variables
19+
V = jm.Placeholder("V")
20+
E = jm.Placeholder("E", ndim=2)
21+
N = jm.Placeholder("N")
22+
x = jm.BinaryVar("x", shape=(V, N))
23+
n = jm.Element("i", belong_to=(0, N))
24+
v = jm.Element("v", belong_to=(0, V))
25+
e = jm.Element("e", belong_to=E)
26+
# set problem
27+
problem = jm.Problem("Graph Coloring")
28+
# set one-hot constraint that each vertex has only one color
29+
30+
#problem += jm.Constraint("one-color", x[v, :].sum() == 1, forall=v)
31+
problem += jm.Constraint("one-color", jm.sum(n, x[v, n]) == 1, forall=v)
32+
# set objective function: minimize edges whose vertices connected by edges are the same color
33+
problem += jm.sum([n, e], x[e[0], n] * x[e[1], n])
34+
return problem
35+
36+
def graph_coloring_instance():
37+
G = nx.Graph()
38+
G.add_nodes_from([0, 1, 2, 3])
39+
G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 3)])
40+
E = [list(edge) for edge in G.edges]
41+
num_color = 3
42+
num_nodes = G.number_of_nodes()
43+
instance_data = {"V": num_nodes, "N": num_color, "E": E}
44+
return instance_data
45+
46+
def create_graph_coloring_operator_ansatz_initial_state(
47+
compiled_instance: jmt.CompiledInstance, num_nodes: int, num_color: int
48+
):
49+
n = num_color * num_nodes
50+
qc = qm_c.QuantumCircuit(n)
51+
var_map = compiled_instance.var_map.var_map["x"]
52+
for i in range(num_nodes):
53+
qc.x(var_map[(i, 0)]) # set all nodes to color 0
54+
return qc
1355

1456
@pytest.fixture
1557
def transpiler():
@@ -133,3 +175,20 @@ def test_qaoa_circuit():
133175
assert isinstance(qp_circuit, qp_c.LinearMappedUnboundParametricQuantumCircuit)
134176
assert qp_circuit.qubit_count == 3
135177
assert qp_circuit.parameter_count == 4
178+
179+
def test_coloring_sample_decode():
180+
problem = graph_coloring_problem()
181+
instance_data = graph_coloring_instance()
182+
compiled_instance = jmt.compile_model(problem, instance_data)
183+
initial_circuit = create_graph_coloring_operator_ansatz_initial_state(compiled_instance, instance_data['V'], instance_data['N'])
184+
qaoa_converter = qm.qaoa.QAOAConverter(compiled_instance)
185+
qaoa_converter.ising_encode(multipliers={"one-color": 1})
186+
187+
qp_transpiler = QuriPartsTranspiler()
188+
sampler = create_qulacs_vector_sampler()
189+
qp_circ = qp_transpiler.transpile_circuit(initial_circuit)
190+
qp_result = sampler(qp_circ, 10)
191+
192+
sampleset = qaoa_converter.decode(qp_transpiler, (qp_result, initial_circuit.num_qubits))
193+
assert sampleset[0].var_values["x"].values == {(0, 0): 1, (1, 0): 1, (2, 0): 1, (3, 0): 1}
194+
assert sampleset[0].num_occurrences == 10

tests/test_bitssample.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ def test_from_int_counts():
3030
for sample in sample_set.bitarrays
3131
)
3232
assert any(
33-
sample.bits == [0, 1] and sample.num_occurrences == 2
33+
sample.bits == [1, 0] and sample.num_occurrences == 2
3434
for sample in sample_set.bitarrays
3535
)
3636
assert any(
37-
sample.bits == [1, 0] and sample.num_occurrences == 1
37+
sample.bits == [0, 1] and sample.num_occurrences == 1
3838
for sample in sample_set.bitarrays
3939
)
4040

@@ -66,7 +66,7 @@ def test_from_int_counts_with_larger_bit_length():
6666
sample_set = BitsSampleSet.from_int_counts(int_counts, bit_length=5)
6767
assert all(len(sample.bits) == 5 for sample in sample_set.bitarrays)
6868
assert any(sample.bits == [0, 0, 0, 0, 0] for sample in sample_set.bitarrays)
69-
assert any(sample.bits == [0, 1, 1, 1, 1] for sample in sample_set.bitarrays)
69+
assert any(sample.bits == [1, 1, 1, 1, 0] for sample in sample_set.bitarrays)
7070

7171

7272
def test_get_most_common_with_ties():
@@ -76,3 +76,4 @@ def test_get_most_common_with_ties():
7676
assert len(most_common) == 3
7777
assert most_common[0].num_occurrences == most_common[1].num_occurrences == 2
7878
assert most_common[2].num_occurrences == 1
79+

0 commit comments

Comments
 (0)