|
27 | 27 | from pygsti.baseobjs.statespace import ExplicitStateSpace as _ExplicitStateSpace
|
28 | 28 | from pygsti.baseobjs.statespace import QuditSpace as _QuditSpace
|
29 | 29 | from pygsti.models import ExplicitOpModel as _ExplicitOpModel
|
30 |
| -from pygsti.forwardsims import MatrixForwardSimulator as _MatrixForwardSimulator |
31 | 30 |
|
32 | 31 | FLOATSIZE = 8 # in bytes: TODO: a better way
|
33 | 32 |
|
@@ -58,8 +57,10 @@ def find_germs(target_model, randomize=True, randomization_strength=1e-2,
|
58 | 57 |
|
59 | 58 | Parameters
|
60 | 59 | ----------
|
61 |
| - target_model : Model |
62 |
| - The model you are aiming to implement. |
| 60 | + target_model : Model or list of Model |
| 61 | + The model you are aiming to implement, or a list of models that are |
| 62 | + copies of the model you are trying to implement (either with or |
| 63 | + without random unitary perturbations applied to the models). |
63 | 64 |
|
64 | 65 | randomize : bool, optional
|
65 | 66 | Whether or not to add random unitary perturbations to the model(s)
|
@@ -187,14 +188,8 @@ def find_germs(target_model, randomize=True, randomization_strength=1e-2,
|
187 | 188 | A list containing the germs making up the germ set.
|
188 | 189 | """
|
189 | 190 | printer = _baseobjs.VerbosityPrinter.create_printer(verbosity, comm)
|
190 |
| - |
191 |
| - if not isinstance(target_model.sim, _MatrixForwardSimulator): |
192 |
| - target_model = target_model.copy() |
193 |
| - target_model.sim = 'matrix' |
194 |
| - |
195 | 191 | modelList = _setup_model_list(target_model, randomize,
|
196 | 192 | randomization_strength, num_gs_copies, seed)
|
197 |
| - |
198 | 193 | gates = list(target_model.operations.keys())
|
199 | 194 | availableGermsList = []
|
200 | 195 | if candidate_germ_counts is None: candidate_germ_counts = {6: 'all upto'}
|
@@ -406,19 +401,7 @@ def find_germs(target_model, randomize=True, randomization_strength=1e-2,
|
406 | 401 | raise ValueError("'{}' is not a valid algorithm "
|
407 | 402 | "identifier.".format(algorithm))
|
408 | 403 |
|
409 |
| - #force the line labels on each circuit to match the state space labels for the target model. |
410 |
| - #this is suboptimal for many-qubit models, so will probably want to revisit this. #TODO |
411 |
| - finalGermList = [] |
412 |
| - for ckt in germList: |
413 |
| - if ckt._static: |
414 |
| - new_ckt = ckt.copy(editable=True) |
415 |
| - new_ckt.line_labels = target_model.state_space.state_space_labels |
416 |
| - new_ckt.done_editing() |
417 |
| - finalGermList.append(new_ckt) |
418 |
| - else: |
419 |
| - ckt.line_labels = target_model.state_space.state_space_labels |
420 |
| - finalGermList.append(ckt) |
421 |
| - return finalGermList |
| 404 | + return germList |
422 | 405 |
|
423 | 406 |
|
424 | 407 | def compute_germ_set_score(germs, target_model=None, neighborhood=None,
|
@@ -1421,10 +1404,6 @@ def test_germ_set_finitel(model, germs_to_test, length, weights=None,
|
1421 | 1404 | eigenvalues (from small to large) of the jacobian^T * jacobian
|
1422 | 1405 | matrix used to determine parameter amplification.
|
1423 | 1406 | """
|
1424 |
| - if not isinstance(model.sim, _MatrixForwardSimulator): |
1425 |
| - model = model.copy() |
1426 |
| - model.sim = 'matrix' |
1427 |
| - |
1428 | 1407 | # Remove any SPAM vectors from model since we only want
|
1429 | 1408 | # to consider the set of *gate* parameters for amplification
|
1430 | 1409 | # and this makes sure our parameter counting is correct
|
@@ -3380,81 +3359,80 @@ def symmetric_low_rank_spectrum_update(update, orig_e, U, proj_U, force_rank_inc
|
3380 | 3359 | #return the new eigenvalues
|
3381 | 3360 | return new_evals, True
|
3382 | 3361 |
|
3383 |
| -# Note: Th function below won't work for our purposes because of the assumptions |
3384 |
| -# about the rank of the update on the nullspace of the matrix we're updating, |
3385 |
| -# but keeping this here commented for future reference. |
3386 |
| -''' |
3387 |
| -def riedel_style_inverse_trace(update, orig_e, U, proj_U, force_rank_increase=True): |
3388 |
| - """ |
3389 |
| - input: |
3390 |
| - |
3391 |
| - update : ndarray |
3392 |
| - symmetric low-rank update to perform. |
3393 |
| - This is the first half the symmetric rank decomposition s.t. |
3394 |
| - [email protected]= the full update matrix. |
3395 |
| - |
3396 |
| - orig_e : ndarray |
3397 |
| - Spectrum of the original matrix. This is a 1-D array. |
3398 |
| - |
3399 |
| - proj_U : ndarray |
3400 |
| - Projector onto the complement of the column space of the |
3401 |
| - original matrix's eigenvectors. |
3402 |
| - |
3403 |
| - output: |
3404 |
| - |
3405 |
| - trace : float |
3406 |
| - Value of the trace of the updated psuedoinverse matrix. |
3407 |
| - |
3408 |
| - updated_rank : int |
3409 |
| - total rank of the updated matrix. |
3410 |
| - |
3411 |
| - rank_increase_flag : bool |
3412 |
| - a flag that is returned to indicate is a candidate germ failed to amplify additional parameters. |
3413 |
| - This indicates things short circuited and so the scoring function should skip this germ. |
3414 |
| - """ |
3415 |
| - |
3416 |
| - #First we need to for the matrix P, whose column space |
3417 |
| - #forms an orthonormal basis for the component of update |
3418 |
| - #that is in the complement of U. |
3419 |
| - |
3420 |
| - proj_update= proj_U@update |
3421 |
| - |
3422 |
| - #Next take the RRQR decomposition of this matrix: |
3423 |
| - q_update, r_update, _ = _sla.qr(proj_update, mode='economic', pivoting=True) |
3424 |
| - |
3425 |
| - #Construct P by taking the columns of q_update corresponding to non-zero values of r_A on the diagonal. |
3426 |
| - nonzero_indices_update= _np.nonzero(_np.diag(r_update)>1e-10) #HARDCODED (threshold is hardcoded) |
3427 |
| - |
3428 |
| - #if the rank doesn't increase then we can't use the Riedel approach. |
3429 |
| - #Abort early and return a flag to indicate the rank did not increase. |
3430 |
| - if len(nonzero_indices_update[0])==0 and force_rank_increase: |
3431 |
| - return None, None, False |
3432 |
| - |
3433 |
| - P= q_update[: , nonzero_indices_update[0]] |
3434 |
| - |
3435 |
| - updated_rank= len(orig_e)+ len(nonzero_indices_update[0]) |
3436 |
| - |
3437 |
| - #Now form the matrix R_update which is given by P.T @ proj_update. |
3438 |
| - R_update= P.T@proj_update |
3439 |
| - |
3440 |
| - #R_update gets concatenated with U.T@update to form |
3441 |
| - #a block column matrixblock_column= np.concatenate([U.T@update, R_update], axis=0) |
3442 |
| - |
3443 |
| - Uta= U.T@update |
3444 |
| - |
3445 |
| - try: |
3446 |
| - RRRDinv= R_update@_np.linalg.inv(R_update.T@R_update) |
3447 |
| - except _np.linalg.LinAlgError as err: |
3448 |
| - print('Numpy thinks this matrix is singular, condition number is: ', _np.linalg.cond(R_update.T@R_update)) |
3449 |
| - print((R_update.T@R_update).shape) |
3450 |
| - raise err |
3451 |
| - pinv_orig_e_mat= _np.diag(1/orig_e) |
3452 |
| - |
3453 |
| - trace= _np.sum(1/orig_e) + _np.trace( RRRDinv@(_np.eye(Uta.shape[1]) + Uta.T@pinv_orig_e_mat@Uta)@RRRDinv.T ) |
| 3362 | +#Note: This function won't work for our purposes because of the assumptions |
| 3363 | +#about the rank of the update on the nullspace of the matrix we're updating, |
| 3364 | +#but keeping this here commented for future reference. |
| 3365 | +#Function for doing fast calculation of the updated inverse trace: |
| 3366 | +#def riedel_style_inverse_trace(update, orig_e, U, proj_U, force_rank_increase=True): |
| 3367 | +# """ |
| 3368 | +# input: |
| 3369 | +# |
| 3370 | +# update : ndarray |
| 3371 | +# symmetric low-rank update to perform. |
| 3372 | +# This is the first half the symmetric rank decomposition s.t. |
| 3373 | +# [email protected]= the full update matrix. |
| 3374 | +# |
| 3375 | +# orig_e : ndarray |
| 3376 | +# Spectrum of the original matrix. This is a 1-D array. |
| 3377 | +# |
| 3378 | +# proj_U : ndarray |
| 3379 | +# Projector onto the complement of the column space of the |
| 3380 | +# original matrix's eigenvectors. |
| 3381 | +# |
| 3382 | +# output: |
| 3383 | +# |
| 3384 | +# trace : float |
| 3385 | +# Value of the trace of the updated psuedoinverse matrix. |
| 3386 | +# |
| 3387 | +# updated_rank : int |
| 3388 | +# total rank of the updated matrix. |
| 3389 | +# |
| 3390 | +# rank_increase_flag : bool |
| 3391 | +# a flag that is returned to indicate is a candidate germ failed to amplify additional parameters. |
| 3392 | +# This indicates things short circuited and so the scoring function should skip this germ. |
| 3393 | +# """ |
| 3394 | +# |
| 3395 | +# #First we need to for the matrix P, whose column space |
| 3396 | +# #forms an orthonormal basis for the component of update |
| 3397 | +# #that is in the complement of U. |
| 3398 | +# |
| 3399 | +# proj_update= proj_U@update |
| 3400 | +# |
| 3401 | +# #Next take the RRQR decomposition of this matrix: |
| 3402 | +# q_update, r_update, _ = _sla.qr(proj_update, mode='economic', pivoting=True) |
| 3403 | +# |
| 3404 | +# #Construct P by taking the columns of q_update corresponding to non-zero values of r_A on the diagonal. |
| 3405 | +# nonzero_indices_update= _np.nonzero(_np.diag(r_update)>1e-10) #HARDCODED (threshold is hardcoded) |
| 3406 | +# |
| 3407 | +# #if the rank doesn't increase then we can't use the Riedel approach. |
| 3408 | +# #Abort early and return a flag to indicate the rank did not increase. |
| 3409 | +# if len(nonzero_indices_update[0])==0 and force_rank_increase: |
| 3410 | +# return None, None, False |
| 3411 | +# |
| 3412 | +# P= q_update[: , nonzero_indices_update[0]] |
| 3413 | +# |
| 3414 | +# updated_rank= len(orig_e)+ len(nonzero_indices_update[0]) |
| 3415 | +# |
| 3416 | +# #Now form the matrix R_update which is given by P.T @ proj_update. |
| 3417 | +# R_update= P.T@proj_update |
| 3418 | +# |
| 3419 | +# #R_update gets concatenated with U.T@update to form |
| 3420 | +# #a block column matrixblock_column= np.concatenate([U.T@update, R_update], axis=0) |
| 3421 | +# |
| 3422 | +# Uta= U.T@update |
| 3423 | +# |
| 3424 | +# try: |
| 3425 | +# RRRDinv= R_update@_np.linalg.inv(R_update.T@R_update) |
| 3426 | +# except _np.linalg.LinAlgError as err: |
| 3427 | +# print('Numpy thinks this matrix is singular, condition number is: ', _np.linalg.cond(R_update.T@R_update)) |
| 3428 | +# print((R_update.T@R_update).shape) |
| 3429 | +# raise err |
| 3430 | +# pinv_orig_e_mat= _np.diag(1/orig_e) |
| 3431 | +# |
| 3432 | +# trace= _np.sum(1/orig_e) + _np.trace( RRRDinv@(_np.eye(Uta.shape[1]) + Uta.T@pinv_orig_e_mat@Uta)@RRRDinv.T ) |
| 3433 | +# |
| 3434 | +# return trace, updated_rank, True |
3454 | 3435 |
|
3455 |
| - return trace, updated_rank, True |
3456 |
| -''' |
3457 |
| - |
3458 | 3436 | def minamide_style_inverse_trace(update, orig_e, U, proj_U, force_rank_increase=False):
|
3459 | 3437 | """
|
3460 | 3438 | This function performs a low-rank update to the components of
|
|
0 commit comments