1
1
# This code is part of a Qiskit project.
2
2
#
3
- # (C) Copyright IBM 2023.
3
+ # (C) Copyright IBM 2023, 2024 .
4
4
#
5
5
# This code is licensed under the Apache License, Version 2.0. You may
6
6
# obtain a copy of this license in the LICENSE.txt file in the root directory
13
13
"""Tests for QuantumRandomAccessEncoding"""
14
14
import itertools
15
15
import unittest
16
- from test . optimization_test_case import QiskitOptimizationTestCase
16
+ from test import QiskitOptimizationTestCase
17
17
18
- from ddt import ddt , data , unpack
19
- import numpy as np
20
18
import networkx as nx
21
-
19
+ import numpy as np
20
+ from ddt import data , ddt , unpack
22
21
from qiskit .circuit import QuantumCircuit
23
- from qiskit .primitives import Estimator
22
+ from qiskit .primitives import Estimator , StatevectorEstimator
24
23
from qiskit .quantum_info import SparsePauliOp
25
24
26
25
from qiskit_optimization .algorithms .qrao import (
27
26
EncodingCommutationVerifier ,
28
27
QuantumRandomAccessEncoding ,
29
28
)
30
- from qiskit_optimization .problems import QuadraticProgram , QuadraticObjective
31
29
from qiskit_optimization .applications import Maxcut
30
+ from qiskit_optimization .problems import QuadraticObjective , QuadraticProgram
32
31
33
32
34
33
class TestQuantumRandomAccessEncoding (QiskitOptimizationTestCase ):
@@ -252,17 +251,20 @@ def test_qrac_unsupported_encoding(self):
252
251
class TestEncodingCommutationVerifier (QiskitOptimizationTestCase ):
253
252
"""Tests for EncodingCommutationVerifier."""
254
253
255
- def check_problem_commutation (self , problem : QuadraticProgram , max_vars_per_qubit : int ):
254
+ def check_problem_commutation (
255
+ self , problem : QuadraticProgram , max_vars_per_qubit : int , version : str
256
+ ):
256
257
"""Utility function to check that the problem commutes with its encoding"""
257
258
encoding = QuantumRandomAccessEncoding (max_vars_per_qubit = max_vars_per_qubit )
258
259
encoding .encode (problem )
259
- estimator = Estimator ()
260
+ estimator = Estimator () if version == "v1" else StatevectorEstimator ()
260
261
verifier = EncodingCommutationVerifier (encoding , estimator )
261
262
self .assertEqual (len (verifier ), 2 ** encoding .num_vars )
262
263
for _ , obj_val , encoded_obj_val in verifier :
263
264
np .testing .assert_allclose (obj_val , encoded_obj_val , atol = 1e-5 )
264
265
265
- def test_encoding_commutation_verifier (self ):
266
+ @data ("v1" , "v2" )
267
+ def test_encoding_commutation_verifier (self , version ):
266
268
"""Test EncodingCommutationVerifier"""
267
269
problem = QuadraticProgram ()
268
270
problem .binary_var ("x" )
@@ -272,11 +274,11 @@ def test_encoding_commutation_verifier(self):
272
274
273
275
encoding = QuantumRandomAccessEncoding (max_vars_per_qubit = 3 )
274
276
encoding .encode (problem )
275
- self .check_problem_commutation (problem , 3 )
277
+ self .check_problem_commutation (problem , 3 , version )
276
278
277
- @data (* itertools .product ([1 , 2 , 3 ], ["minimize" , "maximize" ]))
279
+ @data (* itertools .product ([1 , 2 , 3 ], ["minimize" , "maximize" ], [ "v1" , "v2" ] ))
278
280
@unpack
279
- def test_one_qubit_qrac (self , max_vars_per_qubit , task ):
281
+ def test_one_qubit_qrac (self , max_vars_per_qubit , task , version ):
280
282
"""Test commutation of single qubit QRAC with non-uniform weights, degree 1 terms"""
281
283
282
284
problem = QuadraticProgram ()
@@ -287,15 +289,17 @@ def test_one_qubit_qrac(self, max_vars_per_qubit, task):
287
289
problem .minimize (linear = obj )
288
290
else :
289
291
problem .maximize (linear = obj )
290
- self .check_problem_commutation (problem , max_vars_per_qubit )
292
+ self .check_problem_commutation (problem , max_vars_per_qubit , version )
291
293
292
294
@data (
293
295
* itertools .product (
294
- [1 , 2 , 3 ], [QuadraticObjective .Sense .MINIMIZE , QuadraticObjective .Sense .MAXIMIZE ]
296
+ [1 , 2 , 3 ],
297
+ [QuadraticObjective .Sense .MINIMIZE , QuadraticObjective .Sense .MAXIMIZE ],
298
+ ["v1" , "v2" ],
295
299
)
296
300
)
297
301
@unpack
298
- def test_uniform_weights_degree_2 (self , max_vars_per_qubit , task ):
302
+ def test_uniform_weights_degree_2 (self , max_vars_per_qubit , task , version ):
299
303
"""Test problem commutation with degree 2 terms"""
300
304
# Note that the variable embedding has some qubits with 1, 2, and 3 qubits
301
305
elist = [(0 , 1 ), (1 , 2 ), (2 , 3 ), (3 , 4 ), (4 , 5 ), (5 , 0 ), (0 , 3 ), (1 , 4 ), (2 , 4 )]
@@ -306,25 +310,27 @@ def test_uniform_weights_degree_2(self, max_vars_per_qubit, task):
306
310
maxcut = Maxcut (graph )
307
311
problem = maxcut .to_quadratic_program ()
308
312
problem .objective .sense = task
309
- self .check_problem_commutation (problem , max_vars_per_qubit )
313
+ self .check_problem_commutation (problem , max_vars_per_qubit , version )
310
314
311
- @data (1 , 2 , 3 )
312
- def test_random_unweighted_maxcut (self , max_vars_per_qubit ):
315
+ @data (* itertools .product ([1 , 2 , 3 ], ["v1" , "v2" ]))
316
+ @unpack
317
+ def test_random_unweighted_maxcut (self , max_vars_per_qubit , version ):
313
318
"""Test problem commutation with random unweighted MaxCut"""
314
319
graph = nx .random_regular_graph (3 , 8 )
315
320
maxcut = Maxcut (graph )
316
321
problem = maxcut .to_quadratic_program ()
317
- self .check_problem_commutation (problem , max_vars_per_qubit )
322
+ self .check_problem_commutation (problem , max_vars_per_qubit , version )
318
323
319
- @data (1 , 2 , 3 )
320
- def test_random_weighted_maxcut (self , max_vars_per_qubit ):
324
+ @data (* itertools .product ([1 , 2 , 3 ], ["v1" , "v2" ]))
325
+ @unpack
326
+ def test_random_weighted_maxcut (self , max_vars_per_qubit , version ):
321
327
"""Test problem commutation with random weighted MaxCut"""
322
328
graph = nx .random_regular_graph (3 , 8 )
323
329
for w , v in graph .edges :
324
330
graph [w ][v ]["weight" ] = np .random .randint (1 , 10 )
325
331
maxcut = Maxcut (graph )
326
332
problem = maxcut .to_quadratic_program ()
327
- self .check_problem_commutation (problem , max_vars_per_qubit )
333
+ self .check_problem_commutation (problem , max_vars_per_qubit , version )
328
334
329
335
330
336
if __name__ == "__main__" :
0 commit comments