-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3f2bb53
commit bf012c4
Showing
28 changed files
with
730 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
tests/modules/applications/optimization/mis_temp/mappings/test_neutral_atom.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import unittest | ||
import pickle | ||
|
||
from modules.applications.optimization.mis.mappings.neutral_atom import NeutralAtom | ||
|
||
class TestNeutralAtom(unittest.TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.neutral_atom_instance = NeutralAtom() | ||
with open("tests/modules/applications/optimization/MIS/mappings/MIS_test_graph.pkl", "rb") as file: | ||
cls.graph = pickle.load(file) | ||
cls.config = {} | ||
|
||
def test_get_requirements(self): | ||
requirements = self.neutral_atom_instance.get_requirements() | ||
expected_requirements = [{"name": "pulser", "version": "1.1.1"}] | ||
for req in expected_requirements: | ||
self.assertIn(req, requirements) | ||
|
||
def test_get_parameter_options(self): | ||
options = self.neutral_atom_instance.get_parameter_options() | ||
self.assertEqual(options, {}, "Expected parameter options to be an empty dictionary.") | ||
|
||
def test_map(self): | ||
neutral_atom_problem, mapping_time = self.neutral_atom_instance.map(self.graph, self.config) | ||
|
||
self.assertIn("graph", neutral_atom_problem) | ||
self.assertIn("register", neutral_atom_problem) | ||
|
||
self.assertIsNotNone(neutral_atom_problem["register"], "Expected a valid Pulser register.") | ||
self.assertGreater(mapping_time, 0, "Mapping time should be positive.") | ||
|
||
def test_get_default_submodule(self): | ||
# Test valid submodule retrieval | ||
submodule = self.neutral_atom_instance.get_default_submodule("NeutralAtomMIS") | ||
self.assertIsNotNone(submodule, "Expected 'NeutralAtomMIS' submodule to be returned.") | ||
|
||
# Test invalid submodule option | ||
with self.assertRaises(NotImplementedError): | ||
self.neutral_atom_instance.get_default_submodule("InvalidSubmodule") |
76 changes: 76 additions & 0 deletions
76
tests/modules/applications/optimization/mis_temp/test_mis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import unittest | ||
import networkx as nx | ||
import os | ||
from tempfile import TemporaryDirectory | ||
import logging | ||
|
||
from modules.applications.optimization.mis.mis import MIS | ||
|
||
|
||
class TestMIS(unittest.TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.mis_instance = MIS() | ||
cls.config = {"size": 5, "spacing": 0.5, "filling_fraction": 0.5} | ||
cls.graph = cls.mis_instance.generate_problem(cls.config) | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
del cls.mis_instance | ||
|
||
def test_get_solution_quality_unit(self): | ||
unit = self.mis_instance.get_solution_quality_unit() | ||
self.assertEqual(unit, "Set size", "Incorrect solution quality unit.") | ||
|
||
def test_get_default_submodule(self): | ||
submodule = self.mis_instance.get_default_submodule("NeutralAtom") | ||
self.assertIsNotNone(submodule, "Expected 'NeutralAtom' submodule to be returned.") | ||
with self.assertRaises(NotImplementedError): | ||
self.mis_instance.get_default_submodule("InvalidOption") | ||
|
||
def test_get_parameter_options(self): | ||
options = self.mis_instance.get_parameter_options() | ||
self.assertIn("size", options) | ||
self.assertIn("graph_type", options) | ||
|
||
def test_generate_problem(self): | ||
# Generate with valid configuration | ||
graph = self.mis_instance.generate_problem(self.config) | ||
self.assertIsInstance(graph, nx.Graph) | ||
self.assertGreaterEqual(len(graph.nodes), 1, "Graph should have at least 1 node.") | ||
self.assertGreaterEqual(len(graph.edges), 0, "Graph should have non-negative edges.") | ||
|
||
def test_process_solution(self): | ||
solution = [1, 3] | ||
processed_solution, processing_time = self.mis_instance.process_solution(solution) | ||
self.assertEqual(processed_solution, solution, "Processed solution does not match input.") | ||
self.assertGreaterEqual(processing_time, 0, "Processing time should be positive.") | ||
|
||
def test_validate(self): | ||
logging.disable(logging.WARNING) | ||
self.mis_instance.graph = nx.Graph() | ||
self.mis_instance.graph.add_nodes_from([0, 1, 2]) | ||
self.mis_instance.graph.add_edges_from([(0, 1), (1, 2)]) | ||
|
||
valid_solution = [0, 2] | ||
is_valid, validation_time = self.mis_instance.validate(valid_solution) | ||
self.assertTrue(is_valid, f"Expected valid solution: {valid_solution}") | ||
self.assertGreater(validation_time, 0, "Validation time should be positive.") | ||
|
||
def test_evaluate(self): | ||
solution = list(self.graph.nodes)[:3] | ||
set_size, eval_time = self.mis_instance.evaluate(solution) | ||
self.assertEqual(set_size, len(solution), "Set size mismatch.") | ||
self.assertGreater(eval_time, 0, "Evaluation time should be positive.") | ||
|
||
def test_save(self): | ||
with TemporaryDirectory() as temp_dir: | ||
# Save the graph | ||
self.mis_instance.save(temp_dir, iter_count=1) | ||
|
||
# Check that the file exists and is non-empty | ||
file_path = f"{temp_dir}/graph_iter_1.gpickle" | ||
self.assertTrue(os.path.isfile(file_path), "Graph file not saved.") | ||
self.assertTrue(file_path.endswith(".gpickle"), "File extension mismatch.") | ||
self.assertGreater(os.path.getsize(file_path), 0, "Graph file is empty.") |
65 changes: 65 additions & 0 deletions
65
tests/modules/applications/optimization/sat_temp/mappings/test_choiIsing.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import unittest | ||
import numpy as np | ||
from nnf import Var, And, Or | ||
|
||
from modules.applications.optimization.sat.mappings.choiising import ChoiIsing | ||
|
||
|
||
class TestChoiIsing(unittest.TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.choi_ising_instance = ChoiIsing() | ||
hard_constraints = And([Or([Var("L1"), ~Var("L2")]), Or([~Var("L3"), Var("L4")])]) | ||
soft_constraints = [Or([Var("L5"), ~Var("L6")])] | ||
cls.problem = (hard_constraints, soft_constraints) | ||
cls.config = {"hard_reward": 0.9, "soft_reward": 1.0} | ||
|
||
def test_get_requirements(self): | ||
requirements = self.choi_ising_instance.get_requirements() | ||
self.assertIn({"name": "numpy", "version": "1.26.4"}, requirements) | ||
self.assertIn({"name": "dimod", "version": "0.12.18"}, requirements) | ||
|
||
def test_get_parameter_options(self): | ||
options = self.choi_ising_instance.get_parameter_options() | ||
self.assertIn("hard_reward", options) | ||
self.assertIn("soft_reward", options) | ||
|
||
def test_map(self): | ||
ising_mapping, mapping_time = self.choi_ising_instance.map(self.problem, self.config) | ||
|
||
# Check that mapping results contain the expected keys | ||
self.assertIn("J", ising_mapping) | ||
self.assertIn("t", ising_mapping) | ||
|
||
# Check that J and t have the correct types and shapes | ||
self.assertIsInstance(ising_mapping["J"], np.ndarray) | ||
self.assertIsInstance(ising_mapping["t"], np.ndarray) | ||
self.assertEqual(ising_mapping["J"].shape[0], ising_mapping["J"].shape[1], "J matrix should be square.") | ||
self.assertEqual(len(ising_mapping["t"]), ising_mapping["J"].shape[0], | ||
"t vector length should match J matrix size.") | ||
|
||
self.assertGreater(mapping_time, 0, "Mapping time should be greater than zero.") | ||
|
||
def test_reverse_map(self): | ||
# Create a mock solution | ||
mock_solution = [1, 0, 1, 1, 0] | ||
|
||
# Run reverse_map to convert the solution back | ||
reverse_mapped_solution, reverse_mapping_time = self.choi_ising_instance.reverse_map(mock_solution) | ||
|
||
self.assertIsInstance(reverse_mapped_solution, dict) | ||
self.assertGreater(reverse_mapping_time, 0, "Reverse mapping time should be greater than zero.") | ||
|
||
def test_get_default_submodule(self): | ||
# Check QAOA submodule retrieval | ||
submodule = self.choi_ising_instance.get_default_submodule("QAOA") | ||
self.assertIsNotNone(submodule, "QAOA submodule should not be None") | ||
|
||
# Check PennylaneQAOA submodule retrieval | ||
submodule = self.choi_ising_instance.get_default_submodule("PennylaneQAOA") | ||
self.assertIsNotNone(submodule, "PennylaneQAOA submodule should not be None") | ||
|
||
# Check invalid option raises NotImplementedError | ||
with self.assertRaises(NotImplementedError): | ||
self.choi_ising_instance.get_default_submodule("InvalidSubmodule") |
55 changes: 55 additions & 0 deletions
55
tests/modules/applications/optimization/sat_temp/mappings/test_choiqubo.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import unittest | ||
from nnf import Var, And, Or | ||
|
||
from modules.applications.optimization.sat.mappings.choiqubo import ChoiQUBO | ||
|
||
|
||
class TestChoiQUBO(unittest.TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.choi_qubo_instance = ChoiQUBO() | ||
# Define a problem with both hard and soft constraints | ||
hard_constraints = And([Or([Var("L1"), ~Var("L2")]), Or([~Var("L3"), Var("L4")])]) | ||
soft_constraints = [Or([Var("L5"), ~Var("L6")])] | ||
cls.problem = (hard_constraints, soft_constraints) | ||
cls.config = {"hard_reward": 0.9, "soft_reward": 1.0} | ||
|
||
def test_get_requirements(self): | ||
requirements = self.choi_qubo_instance.get_requirements() | ||
self.assertIn({"name": "nnf", "version": "0.4.1"}, requirements) | ||
|
||
def test_get_parameter_options(self): | ||
options = self.choi_qubo_instance.get_parameter_options() | ||
self.assertIn("hard_reward", options) | ||
self.assertIn("soft_reward", options) | ||
|
||
def test_map(self): | ||
qubo_mapping, mapping_time = self.choi_qubo_instance.map(self.problem, self.config) | ||
|
||
self.assertIn("Q", qubo_mapping) | ||
|
||
q_matrix = qubo_mapping["Q"] | ||
self.assertIsInstance(q_matrix, dict) | ||
for key, value in q_matrix.items(): | ||
self.assertIsInstance(key, tuple, "Expected key to be a tuple") | ||
self.assertTrue(isinstance( | ||
value, float) or isinstance(value, int), "Expected value to be a float or int" | ||
) | ||
|
||
self.assertGreater(mapping_time, 0, "Mapping time should be greater than zero.") | ||
|
||
def test_reverse_map(self): | ||
mock_solution = {i: 1 if i % 2 == 0 else 0 for i in range(len(self.choi_qubo_instance.reverse_dict))} | ||
|
||
reverse_mapped_solution, reverse_mapping_time = self.choi_qubo_instance.reverse_map(mock_solution) | ||
|
||
self.assertIsInstance(reverse_mapped_solution, dict) | ||
self.assertGreater(reverse_mapping_time, 0, "Reverse mapping time should be greater than zero.") | ||
|
||
def test_get_default_submodule(self): | ||
submodule = self.choi_qubo_instance.get_default_submodule("Annealer") | ||
self.assertIsNotNone(submodule, "Annealer submodule should not be None") | ||
|
||
with self.assertRaises(NotImplementedError): | ||
self.choi_qubo_instance.get_default_submodule("InvalidSubmodule") |
63 changes: 63 additions & 0 deletions
63
tests/modules/applications/optimization/sat_temp/mappings/test_dinneenising.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import unittest | ||
import numpy as np | ||
from nnf import Var, And, Or | ||
|
||
from modules.applications.optimization.sat.mappings.dinneenising import DinneenIsing | ||
|
||
|
||
class TestDinneenIsing(unittest.TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.dinneen_ising_instance = DinneenIsing() | ||
# Define a SAT problem with both hard and soft constraints | ||
hard_constraints = And([Or([Var("L1"), ~Var("L2")]), Or([~Var("L3"), Var("L4")])]) | ||
soft_constraints = [Or([Var("L5"), ~Var("L6")])] | ||
cls.problem = (hard_constraints, soft_constraints) | ||
cls.config = {"lagrange": 1.0} | ||
|
||
def test_get_requirements(self): | ||
requirements = self.dinneen_ising_instance.get_requirements() | ||
self.assertIn({"name": "nnf", "version": "0.4.1"}, requirements) | ||
self.assertIn({"name": "numpy", "version": "1.26.4"}, requirements) | ||
self.assertIn({"name": "dimod", "version": "0.12.18"}, requirements) | ||
|
||
def test_get_parameter_options(self): | ||
options = self.dinneen_ising_instance.get_parameter_options() | ||
self.assertIn("lagrange", options) | ||
|
||
def test_map(self): | ||
ising_mapping, mapping_time = self.dinneen_ising_instance.map(self.problem, self.config) | ||
|
||
# Check that mapping results contain the expected "J" and "t" keys | ||
self.assertIn("J", ising_mapping) | ||
self.assertIn("t", ising_mapping) | ||
|
||
# Check that J and t are numpy arrays | ||
j_matrix = ising_mapping["J"] | ||
t_vector = ising_mapping["t"] | ||
self.assertIsInstance(j_matrix, np.ndarray) | ||
self.assertIsInstance(t_vector, np.ndarray) | ||
self.assertEqual(j_matrix.shape[0], j_matrix.shape[1], "J matrix should be square.") | ||
self.assertEqual(len(t_vector), j_matrix.shape[0], "t vector length should match J matrix size.") | ||
|
||
self.assertGreater(mapping_time, 0, "Mapping time should be greater than zero.") | ||
|
||
def test_reverse_map(self): | ||
mock_solution = {i: 1 if i % 2 == 0 else 0 for i in range(len(self.dinneen_ising_instance.problem[0].vars()))} | ||
|
||
reverse_mapped_solution, reverse_mapping_time = self.dinneen_ising_instance.reverse_map(mock_solution) | ||
|
||
# Verify that the output of reverse_map is a dictionary | ||
self.assertIsInstance(reverse_mapped_solution, dict) | ||
self.assertGreater(reverse_mapping_time, 0, "Reverse mapping time should be greater than zero.") | ||
|
||
def test_get_default_submodule(self): | ||
submodule = self.dinneen_ising_instance.get_default_submodule("QAOA") | ||
self.assertIsNotNone(submodule, "QAOA submodule should not be None") | ||
|
||
submodule = self.dinneen_ising_instance.get_default_submodule("PennylaneQAOA") | ||
self.assertIsNotNone(submodule, "PennylaneQAOA submodule should not be None") | ||
|
||
with self.assertRaises(NotImplementedError): | ||
self.dinneen_ising_instance.get_default_submodule("InvalidSubmodule") |
Oops, something went wrong.