@@ -458,7 +458,7 @@ def test_attributes_immutable(self):
458458 with self .assertRaisesRegex (ValueError , "assignment destination is read-only" ):
459459 pauli_lindblad_map .rates [0 ] = 1.0
460460
461- def test_generators (self ):
461+ def test_with_history (self ):
462462 """Test that generators() method returns the same result as
463463 get_qubit_sparse_pauli_list_copy()."""
464464 pauli_lindblad_map = PauliLindbladMap .from_list ([("IIXIZ" , 2 ), ("IIZIX" , 3 )])
@@ -1239,134 +1239,100 @@ def test_signed_sample(self):
12391239 self .assertEqual (len (qubit_sparse_pauli_list ), 5 )
12401240 self .assertEqual (len (signs ), 5 )
12411241
1242- def test_parity_sample (self ):
1243-
1244- # test all negative rates
1245- pauli_lindblad_map = PauliLindbladMap ([("X" , - 1.0 ), ("Y" , - 0.5 )])
1246- probs = pauli_lindblad_map .probabilities ()
1242+ def _assert_parity_sample_results (
1243+ self ,
1244+ plm_to_sample ,
1245+ expected_signs ,
1246+ num_samples = 10000 ,
1247+ seed = 12312 ,
1248+ scale = None ,
1249+ local_scale = None ,
1250+ plm_reference = None ,
1251+ ):
1252+ if plm_reference is None :
1253+ plm_reference = plm_to_sample
1254+
1255+ generators = plm_reference .generators ()
1256+ probs = plm_reference .probabilities ()
12471257 probs_dict = {
12481258 "I" : probs [0 ] * probs [1 ],
12491259 "X" : (1 - probs [0 ]) * probs [1 ],
12501260 "Y" : probs [0 ] * (1 - probs [1 ]),
12511261 "Z" : (1 - probs [0 ]) * (1 - probs [1 ]),
12521262 }
1253- expected_signs = {"I" : False , "X" : True , "Y" : True , "Z" : False }
1254-
1255- num_samples = 10000
1256- signs , qubit_sparse_pauli_list = pauli_lindblad_map .parity_sample (num_samples , 12312 )
12571263
1264+ signs , qubit_sparse_pauli_list , sampled_with_history , sampled_signs = (
1265+ plm_to_sample .parity_sample_with_history (
1266+ num_samples , seed , scale = scale , local_scale = local_scale
1267+ )
1268+ )
12581269 counts = {"I" : 0 , "X" : 0 , "Y" : 0 , "Z" : 0 }
1259- for sign , q in zip (signs , qubit_sparse_pauli_list ):
1270+ for sign , q , _gens , _signs in zip (
1271+ signs , qubit_sparse_pauli_list , sampled_with_history , sampled_signs
1272+ ):
12601273 for symbol in counts :
12611274 if q == QubitSparsePauli (symbol ):
12621275 counts [symbol ] += 1
12631276 self .assertEqual (expected_signs [symbol ], sign )
12641277
1265- for symbol , count in counts .items ():
1266- self .assertTrue (np .abs (count / num_samples - probs_dict [symbol ]) < 1e-2 )
1278+ sampled_sign = False
1279+ sampled_pauli = QubitSparsePauli .from_label ("I" )
1280+ for _i , (_g , _s ) in enumerate (zip (_gens , _signs )):
1281+ if _g :
1282+ sampled_sign = sampled_sign == _s
1283+ sampled_pauli = sampled_pauli .compose (generators [_i ])
12671284
1268- # test all positive rates
1269- pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , 0.5 )])
1270- probs = pauli_lindblad_map .probabilities ()
1271- probs_dict = {
1272- "I" : probs [0 ] * probs [1 ],
1273- "X" : (1 - probs [0 ]) * probs [1 ],
1274- "Y" : probs [0 ] * (1 - probs [1 ]),
1275- "Z" : (1 - probs [0 ]) * (1 - probs [1 ]),
1276- }
1277- expected_signs = {"I" : False , "X" : False , "Y" : False , "Z" : False }
1285+ self .assertEqual (sign , sampled_sign )
1286+ self .assertEqual (q , sampled_pauli )
12781287
1279- num_samples = 10000
1280- signs , qubit_sparse_pauli_list = pauli_lindblad_map .parity_sample (num_samples , 12312 )
1281-
1282- counts = {"I" : 0 , "X" : 0 , "Y" : 0 , "Z" : 0 }
1283- for sign , q in zip (signs , qubit_sparse_pauli_list ):
1284- for symbol in counts :
1285- if q == QubitSparsePauli (symbol ):
1286- counts [symbol ] += 1
1287- self .assertEqual (expected_signs [symbol ], sign )
12881288 for symbol , count in counts .items ():
12891289 self .assertTrue (np .abs (count / num_samples - probs_dict [symbol ]) < 1e-2 )
12901290
1291- # test mix of positive and negative rates
1292- pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
1293- probs = pauli_lindblad_map .probabilities ()
1294- probs_dict = {
1295- "I" : probs [0 ] * probs [1 ],
1296- "X" : (1 - probs [0 ]) * probs [1 ],
1297- "Y" : probs [0 ] * (1 - probs [1 ]),
1298- "Z" : (1 - probs [0 ]) * (1 - probs [1 ]),
1299- }
1300- expected_signs = {"I" : False , "X" : False , "Y" : True , "Z" : True }
1301-
1302- num_samples = 10000
1303- signs , qubit_sparse_pauli_list = pauli_lindblad_map .parity_sample (num_samples , 12312 )
1291+ def test_parity_sample (self ):
13041292
1305- counts = {"I" : 0 , "X" : 0 , "Y" : 0 , "Z" : 0 }
1306- for sign , q in zip (signs , qubit_sparse_pauli_list ):
1307- for symbol in counts :
1308- if q == QubitSparsePauli (symbol ):
1309- counts [symbol ] += 1
1310- self .assertEqual (expected_signs [symbol ], sign )
1293+ with self .subTest ("all negative rates" ):
1294+ pauli_lindblad_map = PauliLindbladMap ([("X" , - 1.0 ), ("Y" , - 0.5 )])
1295+ expected_signs = {"I" : False , "X" : True , "Y" : True , "Z" : False }
13111296
1312- for symbol , count in counts .items ():
1313- self .assertTrue (np .abs (count / num_samples - probs_dict [symbol ]) < 1e-2 )
1297+ self ._assert_parity_sample_results (pauli_lindblad_map , expected_signs )
13141298
1315- # test scale with mix of positive and negative rates
1316- pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
1317- pauli_lindblad_map_downscaled = PauliLindbladMap ([("X" , 0.5 ), ("Y" , - 0.25 )])
1318- probs = pauli_lindblad_map .probabilities ()
1319- probs_dict = {
1320- "I" : probs [0 ] * probs [1 ],
1321- "X" : (1 - probs [0 ]) * probs [1 ],
1322- "Y" : probs [0 ] * (1 - probs [1 ]),
1323- "Z" : (1 - probs [0 ]) * (1 - probs [1 ]),
1324- }
1325- expected_signs = {"I" : False , "X" : False , "Y" : True , "Z" : True }
1299+ with self .subTest ("all positive rates" ):
1300+ pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , 0.5 )])
1301+ expected_signs = {"I" : False , "X" : False , "Y" : False , "Z" : False }
13261302
1327- num_samples = 10000
1328- signs , qubit_sparse_pauli_list = pauli_lindblad_map_downscaled .parity_sample (
1329- num_samples , 12312 , scale = 2.0
1330- )
1303+ self ._assert_parity_sample_results (pauli_lindblad_map , expected_signs )
13311304
1332- counts = {"I" : 0 , "X" : 0 , "Y" : 0 , "Z" : 0 }
1333- for sign , q in zip (signs , qubit_sparse_pauli_list ):
1334- for symbol in counts :
1335- if q == QubitSparsePauli (symbol ):
1336- counts [symbol ] += 1
1337- self .assertEqual (expected_signs [symbol ], sign )
1305+ with self .subTest ("mix of positive and negative rates" ):
1306+ pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
1307+ expected_signs = {"I" : False , "X" : False , "Y" : True , "Z" : True }
13381308
1339- for symbol , count in counts .items ():
1340- self .assertTrue (np .abs (count / num_samples - probs_dict [symbol ]) < 1e-2 )
1309+ self ._assert_parity_sample_results (pauli_lindblad_map , expected_signs )
13411310
1342- # test local_scale with mix of positive and negative rates
1343- pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
1344- pauli_lindblad_map_downscaled = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.25 )])
1345- probs = pauli_lindblad_map .probabilities ()
1346- probs_dict = {
1347- "I" : probs [0 ] * probs [1 ],
1348- "X" : (1 - probs [0 ]) * probs [1 ],
1349- "Y" : probs [0 ] * (1 - probs [1 ]),
1350- "Z" : (1 - probs [0 ]) * (1 - probs [1 ]),
1351- }
1352- expected_signs = {"I" : False , "X" : False , "Y" : True , "Z" : True }
1311+ with self .subTest ("scale with mix of positive and negative rates" ):
1312+ pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
1313+ pauli_lindblad_map_downscaled = PauliLindbladMap ([("X" , 0.5 ), ("Y" , - 0.25 )])
1314+ expected_signs = {"I" : False , "X" : False , "Y" : True , "Z" : True }
13531315
1354- num_samples = 10000
1355- signs , qubit_sparse_pauli_list = pauli_lindblad_map_downscaled .parity_sample (
1356- num_samples , 12312 , local_scale = [1.0 , 2.0 ]
1357- )
1316+ self ._assert_parity_sample_results (
1317+ pauli_lindblad_map_downscaled ,
1318+ expected_signs ,
1319+ scale = 2.0 ,
1320+ plm_reference = pauli_lindblad_map ,
1321+ )
13581322
1359- counts = {"I" : 0 , "X" : 0 , "Y" : 0 , "Z" : 0 }
1360- for sign , q in zip (signs , qubit_sparse_pauli_list ):
1361- for symbol in counts :
1362- if q == QubitSparsePauli (symbol ):
1363- counts [symbol ] += 1
1364- self .assertEqual (expected_signs [symbol ], sign )
1323+ with self .subTest ("local_scale with mix of positive and negative rates" ):
1324+ pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
1325+ pauli_lindblad_map_downscaled = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.25 )])
13651326
1366- for symbol , count in counts .items ():
1367- self .assertTrue (np .abs (count / num_samples - probs_dict [symbol ]) < 1e-2 )
1327+ self ._assert_parity_sample_results (
1328+ pauli_lindblad_map_downscaled ,
1329+ expected_signs ,
1330+ local_scale = [1.0 , 2.0 ],
1331+ plm_reference = pauli_lindblad_map ,
1332+ )
13681333
1369- # test callable without seed
1334+ def test_parity_sample_without_seed (self ):
1335+ pauli_lindblad_map = PauliLindbladMap ([("X" , 1.0 ), ("Y" , - 0.5 )])
13701336 signs , qubit_sparse_pauli_list = pauli_lindblad_map .parity_sample (5 )
13711337 self .assertTrue (isinstance (qubit_sparse_pauli_list , QubitSparsePauliList ))
13721338 self .assertEqual (len (qubit_sparse_pauli_list ), 5 )
0 commit comments