Skip to content

Commit

Permalink
Merge pull request #65 from Jij-Inc/hotfix/decode
Browse files Browse the repository at this point in the history
Fix interpretation of bit order
  • Loading branch information
yuyamashiro authored Sep 3, 2024
2 parents 0385560 + e262c37 commit 27b4515
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 9 deletions.
2 changes: 1 addition & 1 deletion qamomile/core/bitssample.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def from_int_counts(
bitarrays = []
for int_value, count in int_counts.items():
# Convert the integer to a bit array of the specified length
bitarray = list(map(int, bin(int_value)[2:].zfill(bit_length)))
bitarray = list(map(int, bin(int_value)[2:].zfill(bit_length)[::-1]))
bitarrays.append(BitsSample(count, bitarray))
return cls(bitarrays)

Expand Down
69 changes: 65 additions & 4 deletions tests/qiskit/test_transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,59 @@

import pytest
import numpy as np
import jijmodeling as jm
import jijmodeling_transpiler.core as jmt
import networkx as nx
import qiskit
import qiskit.quantum_info as qk_ope
import qiskit.primitives as qk_pr
from qamomile.core.circuit import QuantumCircuit as QamomileCircuit
from qamomile.core.circuit import Parameter
from qamomile.core.operator import Hamiltonian, PauliOperator, Pauli
import qamomile.core.bitssample as qm_bs

import qamomile.core as qm
from qamomile.qiskit.transpiler import QiskitTranspiler
from qamomile.qiskit.exceptions import QamomileQiskitTranspileError

def graph_coloring_problem() -> jm.Problem:
# define variables
V = jm.Placeholder("V")
E = jm.Placeholder("E", ndim=2)
N = jm.Placeholder("N")
x = jm.BinaryVar("x", shape=(V, N))
n = jm.Element("i", belong_to=(0, N))
v = jm.Element("v", belong_to=(0, V))
e = jm.Element("e", belong_to=E)
# set problem
problem = jm.Problem("Graph Coloring")
# set one-hot constraint that each vertex has only one color

#problem += jm.Constraint("one-color", x[v, :].sum() == 1, forall=v)
problem += jm.Constraint("one-color", jm.sum(n, x[v, n]) == 1, forall=v)
# set objective function: minimize edges whose vertices connected by edges are the same color
problem += jm.sum([n, e], x[e[0], n] * x[e[1], n])
return problem

def graph_coloring_instance():
G = nx.Graph()
G.add_nodes_from([0, 1, 2, 3])
G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 3)])
E = [list(edge) for edge in G.edges]
num_color = 3
num_nodes = G.number_of_nodes()
instance_data = {"V": num_nodes, "N": num_color, "E": E}
return instance_data

def create_graph_coloring_operator_ansatz_initial_state(
compiled_instance: jmt.CompiledInstance, num_nodes: int, num_color: int
):
n = num_color * num_nodes
qc = QamomileCircuit(n)
var_map = compiled_instance.var_map.var_map["x"]
for i in range(num_nodes):
qc.x(var_map[(i, 0)]) # set all nodes to color 0
return qc

@pytest.fixture
def transpiler():
Expand Down Expand Up @@ -111,7 +155,24 @@ def test_transpile_hamiltonian(transpiler):
assert np.all(qiskit_hamiltonian.paulis == ['X'])






def test_coloring_sample_decode():
problem = graph_coloring_problem()
instance_data = graph_coloring_instance()
compiled_instance = jmt.compile_model(problem, instance_data)
initial_circuit = create_graph_coloring_operator_ansatz_initial_state(compiled_instance, instance_data['V'], instance_data['N'])
qaoa_converter = qm.qaoa.QAOAConverter(compiled_instance)
qaoa_converter.ising_encode(multipliers={"one-color": 1})

qk_transpiler = QiskitTranspiler()
sampler = qk_pr.StatevectorSampler()
qk_circ = qk_transpiler.transpile_circuit(initial_circuit)
qk_circ.measure_all()
job = sampler.run([qk_circ])

job_result = job.result()

sampleset = qaoa_converter.decode(qk_transpiler, job_result[0].data['meas'])
assert sampleset[0].var_values["x"].values == {(0, 0): 1, (1, 0): 1, (2, 0): 1, (3, 0): 1}
assert sampleset[0].num_occurrences == 1024


61 changes: 60 additions & 1 deletion tests/quri_parts/test_quri_transpiler.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,57 @@
import pytest
import numpy as np
import networkx as nx
import collections
import jijmodeling as jm
import jijmodeling_transpiler.core as jmt
import quri_parts.circuit as qp_c
import quri_parts.core.operator as qp_o
from quri_parts.qulacs.sampler import create_qulacs_vector_sampler
import qamomile.core.circuit as qm_c
import qamomile.core.operator as qm_o
import qamomile.core.bitssample as qm_bs
import qamomile.core as qm
from qamomile.core.converters.qaoa import QAOAConverter
from qamomile.quri_parts.transpiler import QuriPartsTranspiler


def graph_coloring_problem() -> jm.Problem:
# define variables
V = jm.Placeholder("V")
E = jm.Placeholder("E", ndim=2)
N = jm.Placeholder("N")
x = jm.BinaryVar("x", shape=(V, N))
n = jm.Element("i", belong_to=(0, N))
v = jm.Element("v", belong_to=(0, V))
e = jm.Element("e", belong_to=E)
# set problem
problem = jm.Problem("Graph Coloring")
# set one-hot constraint that each vertex has only one color

#problem += jm.Constraint("one-color", x[v, :].sum() == 1, forall=v)
problem += jm.Constraint("one-color", jm.sum(n, x[v, n]) == 1, forall=v)
# set objective function: minimize edges whose vertices connected by edges are the same color
problem += jm.sum([n, e], x[e[0], n] * x[e[1], n])
return problem

def graph_coloring_instance():
G = nx.Graph()
G.add_nodes_from([0, 1, 2, 3])
G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 3)])
E = [list(edge) for edge in G.edges]
num_color = 3
num_nodes = G.number_of_nodes()
instance_data = {"V": num_nodes, "N": num_color, "E": E}
return instance_data

def create_graph_coloring_operator_ansatz_initial_state(
compiled_instance: jmt.CompiledInstance, num_nodes: int, num_color: int
):
n = num_color * num_nodes
qc = qm_c.QuantumCircuit(n)
var_map = compiled_instance.var_map.var_map["x"]
for i in range(num_nodes):
qc.x(var_map[(i, 0)]) # set all nodes to color 0
return qc

@pytest.fixture
def transpiler():
Expand Down Expand Up @@ -133,3 +175,20 @@ def test_qaoa_circuit():
assert isinstance(qp_circuit, qp_c.LinearMappedUnboundParametricQuantumCircuit)
assert qp_circuit.qubit_count == 3
assert qp_circuit.parameter_count == 4

def test_coloring_sample_decode():
problem = graph_coloring_problem()
instance_data = graph_coloring_instance()
compiled_instance = jmt.compile_model(problem, instance_data)
initial_circuit = create_graph_coloring_operator_ansatz_initial_state(compiled_instance, instance_data['V'], instance_data['N'])
qaoa_converter = qm.qaoa.QAOAConverter(compiled_instance)
qaoa_converter.ising_encode(multipliers={"one-color": 1})

qp_transpiler = QuriPartsTranspiler()
sampler = create_qulacs_vector_sampler()
qp_circ = qp_transpiler.transpile_circuit(initial_circuit)
qp_result = sampler(qp_circ, 10)

sampleset = qaoa_converter.decode(qp_transpiler, (qp_result, initial_circuit.num_qubits))
assert sampleset[0].var_values["x"].values == {(0, 0): 1, (1, 0): 1, (2, 0): 1, (3, 0): 1}
assert sampleset[0].num_occurrences == 10
7 changes: 4 additions & 3 deletions tests/test_bitssample.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ def test_from_int_counts():
for sample in sample_set.bitarrays
)
assert any(
sample.bits == [0, 1] and sample.num_occurrences == 2
sample.bits == [1, 0] and sample.num_occurrences == 2
for sample in sample_set.bitarrays
)
assert any(
sample.bits == [1, 0] and sample.num_occurrences == 1
sample.bits == [0, 1] and sample.num_occurrences == 1
for sample in sample_set.bitarrays
)

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


def test_get_most_common_with_ties():
Expand All @@ -76,3 +76,4 @@ def test_get_most_common_with_ties():
assert len(most_common) == 3
assert most_common[0].num_occurrences == most_common[1].num_occurrences == 2
assert most_common[2].num_occurrences == 1

0 comments on commit 27b4515

Please sign in to comment.