14
14
15
15
""" Test Operator construction, including OpPrimitives and singletons. """
16
16
17
+
17
18
import unittest
18
19
from test .aqua import QiskitAquaTestCase
19
20
import itertools
20
21
import numpy as np
22
+ from ddt import ddt , data
21
23
22
24
from qiskit .circuit import QuantumCircuit , QuantumRegister , Instruction
23
25
from qiskit .extensions .exceptions import ExtensionError
24
26
from qiskit .quantum_info .operators import Operator , Pauli
25
- from qiskit .circuit .library import CZGate
27
+ from qiskit .circuit .library import CZGate , ZGate
26
28
27
29
from qiskit .aqua .operators import (
28
- X , Y , Z , I , CX , T , H , PrimitiveOp , SummedOp , PauliOp , Minus , CircuitOp
30
+ X , Y , Z , I , CX , T , H , PrimitiveOp , SummedOp , PauliOp , Minus , CircuitOp , MatrixOp
29
31
)
30
32
31
33
32
34
# pylint: disable=invalid-name
33
35
36
+ @ddt
34
37
class TestOpConstruction (QiskitAquaTestCase ):
35
38
"""Operator Construction tests."""
36
39
@@ -235,7 +238,7 @@ def test_circuit_permute(self):
235
238
c_op_id = c_op_perm .permute (perm )
236
239
self .assertEqual (c_op , c_op_id )
237
240
238
- def test_summed_op (self ):
241
+ def test_summed_op_reduce (self ):
239
242
"""Test SummedOp"""
240
243
sum_op = (X ^ X * 2 ) + (Y ^ Y ) # type: SummedOp
241
244
with self .subTest ('SummedOp test 1' ):
@@ -250,7 +253,7 @@ def test_summed_op(self):
250
253
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'YY' ])
251
254
self .assertListEqual ([op .coeff for op in sum_op ], [2 , 1 , 1 ])
252
255
253
- sum_op = sum_op .simplify ()
256
+ sum_op = sum_op .collapse_summands ()
254
257
with self .subTest ('SummedOp test 2-b' ):
255
258
self .assertEqual (sum_op .coeff , 1 )
256
259
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
@@ -263,7 +266,7 @@ def test_summed_op(self):
263
266
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'YY' , 'XX' ])
264
267
self .assertListEqual ([op .coeff for op in sum_op ], [2 , 1 , 1 , 2 ])
265
268
266
- sum_op = sum_op .simplify ()
269
+ sum_op = sum_op .reduce ()
267
270
with self .subTest ('SummedOp test 3-b' ):
268
271
self .assertEqual (sum_op .coeff , 1 )
269
272
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
@@ -275,7 +278,7 @@ def test_summed_op(self):
275
278
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
276
279
self .assertListEqual ([op .coeff for op in sum_op ], [2 , 1 ])
277
280
278
- sum_op = sum_op .simplify ()
281
+ sum_op = sum_op .collapse_summands ()
279
282
with self .subTest ('SummedOp test 4-b' ):
280
283
self .assertEqual (sum_op .coeff , 1 )
281
284
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
@@ -288,7 +291,7 @@ def test_summed_op(self):
288
291
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'YY' ])
289
292
self .assertListEqual ([op .coeff for op in sum_op ], [4 , 2 , 1 ])
290
293
291
- sum_op = sum_op .simplify ()
294
+ sum_op = sum_op .collapse_summands ()
292
295
with self .subTest ('SummedOp test 5-b' ):
293
296
self .assertEqual (sum_op .coeff , 1 )
294
297
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
@@ -301,7 +304,7 @@ def test_summed_op(self):
301
304
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'XX' , 'YY' ])
302
305
self .assertListEqual ([op .coeff for op in sum_op ], [4 , 2 , 2 , 1 ])
303
306
304
- sum_op = sum_op .simplify ()
307
+ sum_op = sum_op .collapse_summands ()
305
308
with self .subTest ('SummedOp test 6-b' ):
306
309
self .assertEqual (sum_op .coeff , 1 )
307
310
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
@@ -310,11 +313,11 @@ def test_summed_op(self):
310
313
sum_op = SummedOp ([X ^ X * 2 , Y ^ Y ], 2 )
311
314
sum_op += sum_op
312
315
with self .subTest ('SummedOp test 7-a' ):
313
- self .assertEqual (sum_op .coeff , 4 )
314
- self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
315
- self .assertListEqual ([op .coeff for op in sum_op ], [2 , 1 ])
316
+ self .assertEqual (sum_op .coeff , 1 )
317
+ self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'XX' , 'YY' ])
318
+ self .assertListEqual ([op .coeff for op in sum_op ], [4 , 2 , 4 , 2 ])
316
319
317
- sum_op = sum_op .simplify ()
320
+ sum_op = sum_op .collapse_summands ()
318
321
with self .subTest ('SummedOp test 7-b' ):
319
322
self .assertEqual (sum_op .coeff , 1 )
320
323
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' ])
@@ -326,12 +329,28 @@ def test_summed_op(self):
326
329
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'XX' , 'ZZ' ])
327
330
self .assertListEqual ([op .coeff for op in sum_op ], [4 , 2 , 6 , 3 ])
328
331
329
- sum_op = sum_op .simplify ()
332
+ sum_op = sum_op .collapse_summands ()
330
333
with self .subTest ('SummedOp test 8-b' ):
331
334
self .assertEqual (sum_op .coeff , 1 )
332
335
self .assertListEqual ([str (op .primitive ) for op in sum_op ], ['XX' , 'YY' , 'ZZ' ])
333
336
self .assertListEqual ([op .coeff for op in sum_op ], [10 , 2 , 3 ])
334
337
338
+ def test_summed_op_equals (self ):
339
+ """Test corner cases of SummedOp's equals function."""
340
+ with self .subTest ('multiplicative factor' ):
341
+ self .assertEqual (2 * X , X + X )
342
+
343
+ with self .subTest ('commutative' ):
344
+ self .assertEqual (X + Z , Z + X )
345
+
346
+ with self .subTest ('circuit and paulis' ):
347
+ z = CircuitOp (ZGate ())
348
+ self .assertEqual (Z + z , z + Z )
349
+
350
+ with self .subTest ('matrix op and paulis' ):
351
+ z = MatrixOp ([[1 , 0 ], [0 , - 1 ]])
352
+ self .assertEqual (Z + z , z + Z )
353
+
335
354
def test_circuit_compose_register_independent (self ):
336
355
"""Test that CircuitOp uses combines circuits independent of the register.
337
356
@@ -344,13 +363,14 @@ def test_circuit_compose_register_independent(self):
344
363
345
364
self .assertEqual (composed .num_qubits , 2 )
346
365
347
- def test_pauli_op_hashing (self ):
366
+ @data (Z , CircuitOp (ZGate ()), MatrixOp ([[1 , 0 ], [0 , - 1 ]]))
367
+ def test_op_hashing (self , op ):
348
368
"""Regression test against faulty set comparison.
349
369
350
370
Set comparisons rely on a hash table which requires identical objects to have identical
351
- hashes. Thus, the PauliOp .__hash__ should support this requirement.
371
+ hashes. Thus, the PrimitiveOp .__hash__ should support this requirement.
352
372
"""
353
- self .assertEqual (set ([2 * Z ]), set ([2 * Z ]))
373
+ self .assertEqual (set ([2 * op ]), set ([2 * op ]))
354
374
355
375
356
376
if __name__ == '__main__' :
0 commit comments