From daf6c4f8d1c5f9b661d0e25640f717df03642a3a Mon Sep 17 00:00:00 2001 From: Boro Sofranac Date: Mon, 5 Feb 2024 14:31:31 +0000 Subject: [PATCH 1/5] improve QUBO converter performance by building an upper triangular matrix directly --- .../problems/quadratic_expression.py | 9 ++++-- test/problems/test_quadratic_expression.py | 32 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/qiskit_optimization/problems/quadratic_expression.py b/qiskit_optimization/problems/quadratic_expression.py index 2e1501260..a1123f3ce 100644 --- a/qiskit_optimization/problems/quadratic_expression.py +++ b/qiskit_optimization/problems/quadratic_expression.py @@ -112,8 +112,13 @@ def _coeffs_to_dok_matrix( i = self.quadratic_program.variables_index[i] if isinstance(j, str): j = self.quadratic_program.variables_index[j] - coeffs[i, j] = value - coefficients = coeffs + + if i > j: + coeffs[j, i] += value + else: + coeffs[i, j] += value + + return coeffs else: raise QiskitOptimizationError(f"Unsupported format for coefficients: {coefficients}") return self._triangle_matrix(coefficients) diff --git a/test/problems/test_quadratic_expression.py b/test/problems/test_quadratic_expression.py index da3b18c62..17874524c 100644 --- a/test/problems/test_quadratic_expression.py +++ b/test/problems/test_quadratic_expression.py @@ -273,6 +273,38 @@ def test_str_repr(self): self.assertEqual(str(expr), expected) self.assertEqual(repr(expr), f"") + def test_coeffs_to_dok_matrix(self): + """test that the conversion from coefficients to a dok_matrix is correct""" + num_vars = 4 + quadratic_program = QuadraticProgram() + for _ in range(num_vars): + quadratic_program.binary_var() + + coefficients = { + (1, 1): 1, + (1, 2): 2, + (2, 1): 3, + (1, 3): 3, + (3, 1): 3, + (2, 2): 4, + (2, 3): 12, + (3, 3): 9, + } + + quadratic = QuadraticExpression(quadratic_program, coefficients) + + res = quadratic._coeffs_to_dok_matrix(coefficients) + + expected = dok_matrix((num_vars, num_vars)) + expected[1, 1] = 1 + expected[1, 2] = 5 + expected[1, 3] = 6 + expected[2, 2] = 4 + expected[2, 3] = 12 + expected[3, 3] = 9 + + self.assertTrue(np.allclose(expected.todense(), res.todense())) + if __name__ == "__main__": unittest.main() From dfd58add268aa71caac9d4db5579f4045c7a5a98 Mon Sep 17 00:00:00 2001 From: Boro Sofranac Date: Mon, 5 Feb 2024 17:51:06 +0000 Subject: [PATCH 2/5] update copyright headers --- qiskit_optimization/problems/quadratic_expression.py | 2 +- test/problems/test_quadratic_expression.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit_optimization/problems/quadratic_expression.py b/qiskit_optimization/problems/quadratic_expression.py index a1123f3ce..05e1ecbf8 100644 --- a/qiskit_optimization/problems/quadratic_expression.py +++ b/qiskit_optimization/problems/quadratic_expression.py @@ -1,6 +1,6 @@ # This code is part of a Qiskit project. # -# (C) Copyright IBM 2019, 2023. +# (C) Copyright IBM 2019, 2024. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory diff --git a/test/problems/test_quadratic_expression.py b/test/problems/test_quadratic_expression.py index 17874524c..394bc94c9 100644 --- a/test/problems/test_quadratic_expression.py +++ b/test/problems/test_quadratic_expression.py @@ -1,6 +1,6 @@ # This code is part of a Qiskit project. # -# (C) Copyright IBM 2020, 2023. +# (C) Copyright IBM 2020, 2024. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory From 26b5ca2078e0298c02c6c0724e647edcd55b2b4e Mon Sep 17 00:00:00 2001 From: Boro Sofranac Date: Fri, 15 Mar 2024 14:41:00 +0000 Subject: [PATCH 3/5] do not use the new update rule in conversion for python versions older than 3.9 --- .../problems/quadratic_expression.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/qiskit_optimization/problems/quadratic_expression.py b/qiskit_optimization/problems/quadratic_expression.py index 05e1ecbf8..876c73746 100644 --- a/qiskit_optimization/problems/quadratic_expression.py +++ b/qiskit_optimization/problems/quadratic_expression.py @@ -17,6 +17,7 @@ import numpy as np from numpy import ndarray from scipy.sparse import spmatrix, dok_matrix, tril, triu +import sys from .quadratic_program_element import QuadraticProgramElement from ..exceptions import QiskitOptimizationError @@ -105,6 +106,10 @@ def _coeffs_to_dok_matrix( if isinstance(coefficients, (list, ndarray, spmatrix)): coefficients = dok_matrix(coefficients) elif isinstance(coefficients, dict): + + # Check if the python version is at least 3.9. See pull request #594 for more details on this check. + new_update_rule = sys.version_info >= (3,9) + n = self.quadratic_program.get_num_vars() coeffs = dok_matrix((n, n)) for (i, j), value in coefficients.items(): @@ -113,12 +118,18 @@ def _coeffs_to_dok_matrix( if isinstance(j, str): j = self.quadratic_program.variables_index[j] - if i > j: - coeffs[j, i] += value + if new_update_rule: + if i > j: + coeffs[j, i] += value + else: + coeffs[i, j] += value else: - coeffs[i, j] += value + coeffs[i, j] = value - return coeffs + if new_update_rule: + return coeffs + else: + coefficients = coeffs else: raise QiskitOptimizationError(f"Unsupported format for coefficients: {coefficients}") return self._triangle_matrix(coefficients) From ff8dc18fc560e8c125d720571ed6fe5a88f00798 Mon Sep 17 00:00:00 2001 From: Boro Sofranac Date: Fri, 15 Mar 2024 14:44:07 +0000 Subject: [PATCH 4/5] some linter fixes --- qiskit_optimization/problems/quadratic_expression.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qiskit_optimization/problems/quadratic_expression.py b/qiskit_optimization/problems/quadratic_expression.py index 876c73746..460fdff9f 100644 --- a/qiskit_optimization/problems/quadratic_expression.py +++ b/qiskit_optimization/problems/quadratic_expression.py @@ -14,10 +14,10 @@ from typing import List, Union, Dict, Tuple, Any +import sys import numpy as np from numpy import ndarray from scipy.sparse import spmatrix, dok_matrix, tril, triu -import sys from .quadratic_program_element import QuadraticProgramElement from ..exceptions import QiskitOptimizationError @@ -107,7 +107,8 @@ def _coeffs_to_dok_matrix( coefficients = dok_matrix(coefficients) elif isinstance(coefficients, dict): - # Check if the python version is at least 3.9. See pull request #594 for more details on this check. + # Check if the python version is at least 3.9. + # See pull request #594 for more details why we do this check. new_update_rule = sys.version_info >= (3,9) n = self.quadratic_program.get_num_vars() From 7dbdf4240e009d79b622f932cc7e8f621dfa6b4e Mon Sep 17 00:00:00 2001 From: Boro Sofranac Date: Fri, 15 Mar 2024 15:39:51 +0000 Subject: [PATCH 5/5] reformat to conform with style --- qiskit_optimization/problems/quadratic_expression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_optimization/problems/quadratic_expression.py b/qiskit_optimization/problems/quadratic_expression.py index 460fdff9f..c6a7b8a7d 100644 --- a/qiskit_optimization/problems/quadratic_expression.py +++ b/qiskit_optimization/problems/quadratic_expression.py @@ -109,7 +109,7 @@ def _coeffs_to_dok_matrix( # Check if the python version is at least 3.9. # See pull request #594 for more details why we do this check. - new_update_rule = sys.version_info >= (3,9) + new_update_rule = sys.version_info >= (3, 9) n = self.quadratic_program.get_num_vars() coeffs = dok_matrix((n, n))