pygsti.tools.optools¶

Utility functions operating on operation matrices

Module Contents¶

Attributes¶

pygsti.tools.optools.IMAG_TOL = 1e-07
pygsti.tools.optools._flat_mut_blks(i, j, block_dims)
pygsti.tools.optools._hack_sqrtm(a)
pygsti.tools.optools.fidelity(a, b)

Returns the quantum state fidelity between density matrices.

This given by:

F = Tr( sqrt{ sqrt(a) * b * sqrt(a) } )^2

To compute process fidelity, pass this function the Choi matrices of the two processes, or just call :function:`entanglement_fidelity` with the operation matrices.

Parameters
• a (numpy array) – First density matrix.

• b (numpy array) – Second density matrix.

Returns

float – The resulting fidelity.

pygsti.tools.optools.frobeniusdist(a, b)

Returns the frobenius distance between gate or density matrices.

This is given by :

sqrt( sum( (a_ij-b_ij)^2 ) )

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

Returns

float – The resulting frobenius distance.

pygsti.tools.optools.frobeniusdist_squared(a, b)

Returns the square of the frobenius distance between gate or density matrices.

This is given by :

sum( (A_ij-B_ij)^2 )

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

Returns

float – The resulting frobenius distance.

pygsti.tools.optools.residuals(a, b)

Calculate residuals between the elements of two matrices

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

Returns

np.array – residuals

pygsti.tools.optools.tracenorm(a)

Compute the trace norm of matrix a given by:

Tr( sqrt{ a^dagger * a } )

Parameters

a (numpy array) – The matrix to compute the trace norm of.

Returns

float

pygsti.tools.optools.tracedist(a, b)

Compute the trace distance between matrices.

This is given by:

D = 0.5 * Tr( sqrt{ (a-b)^dagger * (a-b) } )

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

Returns

float

pygsti.tools.optools.diamonddist(a, b, mx_basis='pp', return_x=False)

Returns the approximate diamond norm describing the difference between gate matrices.

This is given by :

D = ||a - b ||_diamond = sup_rho || AxI(rho) - BxI(rho) ||_1

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

• mx_basis (Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• return_x (bool, optional) – Whether to return a numpy array encoding the state (rho) at which the maximal trace distance occurs.

Returns

• dm (float) – Diamond norm

• W (numpy array) – Only returned if return_x = True. Encodes the state rho, such that dm = trace( |(J(a)-J(b)).T * W| ).

pygsti.tools.optools.jtracedist(a, b, mx_basis='pp')

Compute the Jamiolkowski trace distance between operation matrices.

This is given by:

D = 0.5 * Tr( sqrt{ (J(a)-J(b))^2 } )

where J(.) is the Jamiolkowski isomorphism map that maps a operation matrix to it’s corresponding Choi Matrix.

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

Returns

float

pygsti.tools.optools.entanglement_fidelity(a, b, mx_basis='pp')

Returns the “entanglement” process fidelity between gate matrices.

This is given by:

F = Tr( sqrt{ sqrt(J(a)) * J(b) * sqrt(J(a)) } )^2

where J(.) is the Jamiolkowski isomorphism map that maps a operation matrix to it’s corresponding Choi Matrix.

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The basis of the matrices. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

Returns

float

pygsti.tools.optools.average_gate_fidelity(a, b, mx_basis='pp')

Computes the average gate fidelity (AGF) between two gates.

Average gate fidelity (F_g) is related to entanglement fidelity (F_p), via:

F_g = (d * F_p + 1)/(1 + d),

where d is the Hilbert space dimension. This formula, and the definition of AGF, can be found in Phys. Lett. A 303 249-252 (2002).

Parameters
• a (array or gate) – The gate to compute the AGI to b of. E.g., an imperfect implementation of b.

• b (array or gate) – The gate to compute the AGI to a of. E.g., the target gate corresponding to a.

• mx_basis ({"std","gm","pp"} or Basis object, optional) – The basis of the matrices.

Returns

AGI (float) – The AGI of a to b.

pygsti.tools.optools.average_gate_infidelity(a, b, mx_basis='gm')

Computes the average gate infidelity (AGI) between two gates.

Average gate infidelity is related to entanglement infidelity (EI) via:

AGI = (d * (1-EI) + 1)/(1 + d),

where d is the Hilbert space dimension. This formula, and the definition of AGI, can be found in Phys. Lett. A 303 249-252 (2002).

Parameters
• a (array or gate) – The gate to compute the AGI to b of. E.g., an imperfect implementation of b.

• b (array or gate) – The gate to compute the AGI to a of. E.g., the target gate corresponding to a.

• mx_basis ({"std","gm","pp"} or Basis object, optional) – The basis of the matrices.

Returns

float

pygsti.tools.optools.entanglement_infidelity(a, b, mx_basis='pp')

Returns the entanglement infidelity (EI) between gate matrices.

This i given by:

EI = 1 - Tr( sqrt{ sqrt(J(a)) * J(b) * sqrt(J(a)) } )^2

where J(.) is the Jamiolkowski isomorphism map that maps a operation matrix to it’s corresponding Choi Matrix.

Parameters
• a (numpy array) – First matrix.

• b (numpy array) – Second matrix.

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The basis of the matrices. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

Returns

EI (float) – The EI of a to b.

pygsti.tools.optools.gateset_infidelity(model, target_model, itype='EI', weights=None, mx_basis=None)

Computes the average-over-gates of the infidelity between gates in model and the gates in target_model.

If itype is ‘EI’ then the “infidelity” is the entanglement infidelity; if itype is ‘AGI’ then the “infidelity” is the average gate infidelity (AGI and EI are related by a dimension dependent constant).

This is the quantity that RB error rates are sometimes claimed to be related to directly related.

Parameters
• model (Model) – The model to calculate the average infidelity, to target_model, of.

• target_model (Model) – The model to calculate the average infidelity, to model, of.

• itype (str, optional) – The infidelity type. Either ‘EI’, corresponding to entanglement infidelity, or ‘AGI’, corresponding to average gate infidelity.

• weights (dict, optional) – If not None, a dictionary of floats, whereby the keys are the gates in model and the values are, possibly unnormalized, probabilities. These probabilities corresponding to the weighting in the average, so if the model contains gates A and B and weights[A] = 2 and weights[B] = 1 then the output is Inf(A)*2/3 + Inf(B)/3 where Inf(X) is the infidelity (to the corresponding element in the other model) of X. If None, a uniform-average is taken, equivalent to setting all the weights to 1.

• mx_basis ({"std","gm","pp"} or Basis object, optional) – The basis of the models. If None, the basis is obtained from the model.

Returns

float – The weighted average-over-gates infidelity between the two models.

pygsti.tools.optools.unitarity(a, mx_basis='gm')

Returns the “unitarity” of a channel.

Unitarity is defined as in Wallman et al, ``Estimating the Coherence of noise’’ NJP 17 113020 (2015). The unitarity is given by (Prop 1 in Wallman et al):

u(a) = Tr( A_u^{dagger} A_u ) / (d^2 - 1),

where A_u is the unital submatrix of a, and d is the dimension of the Hilbert space. When a is written in any basis for which the first element is the normalized identity (e.g., the pp or gm bases), The unital submatrix of a is the matrix obtained when the top row and left hand column is removed from a.

Parameters
• a (array or gate) – The gate for which the unitarity is to be computed.

• mx_basis ({"std","gm","pp"} or a Basis object, optional) – The basis of the matrix.

Returns

float

pygsti.tools.optools.fidelity_upper_bound(operation_mx)

Get an upper bound on the fidelity of the given operation matrix with any unitary operation matrix.

The closeness of the result to one tells

how “unitary” the action of operation_mx is.

Parameters

operation_mx (numpy array) – The operation matrix to act on.

Returns

float – The resulting upper bound on fidelity(operation_mx, anyUnitaryGateMx)

pygsti.tools.optools.compute_povm_map(model, povmlbl)

Constructs a gate-like quantity for the POVM within model.

This is done by embedding the k-outcome classical output space of the POVM in the Hilbert-Schmidt space of k by k density matrices by placing the classical probability distribution along the diagonal of the density matrix. Currently, this is only implemented for the case when k equals d, the dimension of the POVM’s Hilbert space.

Parameters
• model (Model) – The model supplying the POVM effect vectors and the basis those vectors are in.

• povmlbl (str) – The POVM label

Returns

numpy.ndarray – The matrix of the “POVM map” in the model.basis basis.

pygsti.tools.optools.povm_fidelity(model, target_model, povmlbl)

Computes the process (entanglement) fidelity between POVM maps.

Parameters
• model (Model) – The model the POVM belongs to.

• target_model (Model) – The target model (which also has povmlbl).

• povmlbl (Label) – Label of the POVM to get the fidelity of.

Returns

float

pygsti.tools.optools.povm_jtracedist(model, target_model, povmlbl)

Computes the Jamiolkowski trace distance between POVM maps using jtracedist().

Parameters
• model (Model) – The model the POVM belongs to.

• target_model (Model) – The target model (which also has povmlbl).

• povmlbl (Label) – Label of the POVM to get the trace distance of.

Returns

float

pygsti.tools.optools.povm_diamonddist(model, target_model, povmlbl)

Computes the diamond distance between POVM maps using diamonddist().

Parameters
• model (Model) – The model the POVM belongs to.

• target_model (Model) – The target model (which also has povmlbl).

• povmlbl (Label) – Label of the POVM to get the diamond distance of.

Returns

float

pygsti.tools.optools.decompose_gate_matrix(operation_mx)

Decompse a gate matrix into fixed points, axes of rotation, angles of rotation, and decay rates.

This funtion computes how the action of a operation matrix can be is decomposed into fixed points, axes of rotation, angles of rotation, and decays. Also determines whether a gate appears to be valid and/or unitary.

Parameters

operation_mx (numpy array) – The operation matrix to act on.

Returns

dict

A dictionary describing the decomposed action. Keys are:

’isValid’bool

whether decomposition succeeded

’isUnitary’bool

whether operation_mx describes unitary action

’fixed point’numpy array

the fixed point of the action

’axis of rotation’numpy array or nan

the axis of rotation

’decay of diagonal rotation terms’float

decay of diagonal terms

’rotating axis 1’numpy array or nan

1st axis orthogonal to axis of rotation

’rotating axis 2’numpy array or nan

2nd axis orthogonal to axis of rotation

’decay of off diagonal rotation terms’float

decay of off-diagonal terms

’pi rotations’float

angle of rotation in units of pi radians

pygsti.tools.optools.state_to_dmvec(psi)

Compute the vectorized density matrix which acts as the state psi.

This is just the outer product map |psi> => |psi><psi| with the output flattened, i.e. dot(psi, conjugate(psi).T).

Parameters

psi (numpy array) – The state vector.

Returns

numpy array – The vectorized density matrix.

pygsti.tools.optools.dmvec_to_state(dmvec, tol=1e-06)

Compute the pure state describing the action of density matrix vector dmvec.

If dmvec represents a mixed state, ValueError is raised.

Parameters
• dmvec (numpy array) – The vectorized density matrix, assumed to be in the standard (matrix unit) basis.

• tol (float, optional) – tolerance for determining whether an eigenvalue is zero.

Returns

numpy array – The pure state, as a column vector of shape = (N,1)

pygsti.tools.optools.unitary_to_process_mx(u)

Compute the superoperator corresponding to unitary matrix u.

Computes a super-operator (that acts on (row)-vectorized density matrices) from a unitary operator (matrix) u which acts on state vectors. This super-operator is given by the tensor product of u and conjugate(u), i.e. kron(u,u.conj).

Parameters

u (numpy array) – The unitary matrix which acts on state vectors.

Returns

numpy array – The super-operator process matrix.

pygsti.tools.optools.process_mx_to_unitary(superop)

Compute the unitary corresponding to the (unitary-action!) super-operator superop.

This function assumes superop acts on (row)-vectorized density matrices. The super-operator must be of the form kron(U,U.conj) or an error will be thrown.

Parameters

superop (numpy array) – The superoperator matrix which acts on vectorized density matrices (in the ‘std’ matrix-unit basis).

Returns

numpy array – The unitary matrix which acts on state vectors.

pygsti.tools.optools.spam_error_generator(spamvec, target_spamvec, mx_basis, typ='logGTi')

Construct an error generator from a SPAM vector and it’s target.

Computes the value of the error generator given by errgen = log( diag(spamvec / target_spamvec) ), where division is element-wise. This results in a (non-unique) error generator matrix E such that spamvec = exp(E) * target_spamvec.

Note: This is currently of very limited use, as the above algorithm fails whenever target_spamvec has zero elements where spamvec doesn’t.

Parameters
• spamvec (ndarray) – The SPAM vector.

• target_spamvec (ndarray) – The target SPAM vector.

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• typ ({"logGTi"}) –

The type of error generator to compute. Allowed values are:

• ”logGTi” : errgen = log( diag(spamvec / target_spamvec) )

Returns

errgen (ndarray) – The error generator.

pygsti.tools.optools.error_generator(gate, target_op, mx_basis, typ='logG-logT', logG_weight=None)

Construct the error generator from a gate and its target.

Computes the value of the error generator given by errgen = log( inv(target_op) * gate ), so that gate = target_op * exp(errgen).

Parameters
• gate (ndarray) – The operation matrix

• target_op (ndarray) – The target operation matrix

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• typ ({"logG-logT", "logTiG", "logGTi"}) –

The type of error generator to compute. Allowed values are:

• ”logG-logT” : errgen = log(gate) - log(target_op)

• ”logTiG” : errgen = log( dot(inv(target_op), gate) )

• ”logGTi” : errgen = log( dot(gate,inv(target_op)) )

• logG_weight (float or None (default)) – Regularization weight for logG-logT penalty of approximate logG. If None, the default weight in approximate_matrix_log() is used. Note that this will result in a logG close to logT, but G may not exactly equal exp(logG). If self-consistency with func:operation_from_error_generator is desired, consider testing lower (or zero) regularization weight.

Returns

errgen (ndarray) – The error generator.

pygsti.tools.optools.operation_from_error_generator(error_gen, target_op, mx_basis, typ='logG-logT')

Construct a gate from an error generator and a target gate.

Inverts the computation done in error_generator() and returns the value of the gate given by gate = target_op * exp(error_gen).

Parameters
• error_gen (ndarray) – The error generator matrix

• target_op (ndarray) – The target operation matrix

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• typ ({"logG-logT", "logG-logT-quick", "logTiG", "logGTi"}) –

The type of error generator to invert. Allowed values are:

• ”logG-logT” : gate = exp( errgen + log(target_op) ) using internal logm

• ”logG-logT-quick” : gate = exp( errgen + log(target_op) ) using SciPy logm

• ”logTiG” : gate = dot( target_op, exp(errgen) )

• ”logGTi” : gate = dot( exp(errgen), target_op )

Returns

ndarray – The operation matrix.

pygsti.tools.optools.std_scale_factor(dim, projection_type)

Gets the scaling factors required to turn std_error_generators() output into projectors.

Returns the multiplicative scaling that should be applied to the output of :func”std_error_generators, before using them as projectors, in order to compute the “standard” reported projection onto that type of error (i.e. the coefficient of the standard generator terms built un-normalized-Paulis).

Parameters
• dim (int) – The dimension of the error generators; also the associated gate dimension. This must be a perfect square, as sqrt(dim) is the dimension of density matrices. For a single qubit, dim == 4.

• projection_type ({"hamiltonian", "stochastic", "affine"}) – The type/class of error generators to get the scaling for.

Returns

float

pygsti.tools.optools.std_error_generators(dim, projection_type, projection_basis)

Compute the gate error generators for a standard set of errors.

Specifically, these errors can correspond to “Hamiltonian”-, “Stochastic”-, or “Affine”-type errors in terms of the elements of the specified basis.

Parameters
• dim (int) – The dimension of the error generators to be returned. This is also the associated gate dimension, and must be a perfect square, as sqrt(dim) is the dimension of density matrices. For a single qubit, dim == 4.

• projection_type ({"hamiltonian", "stochastic", "affine"}) – The type of error generators to construct. If “hamiltonian”, then the Hamiltonian generators which take a density matrix rho -> -i*[ H, rho ] for Pauli-product matrix H. If “stochastic”, then the Stochastic error generators which take rho -> P*rho*P for Pauli-product matrix P. If “affine”, then the affine generators which take rho -> P.

• projection_basis ({'std', 'gm', 'pp', 'qt'}) – Which basis is used to construct the error generators. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp) and Qutrit (qt).

Returns

generators (numpy.ndarray) – An array of shape (#basis-elements,dim,dim). generators[i] is the generator corresponding to the ith basis matrix in the std (matrix unit) basis. (Note that in most cases #basis-elements == dim, so the size of generators is (dim,dim,dim) ). Each generator is normalized so that as a vector it has unit Frobenius norm.

pygsti.tools.optools.std_errorgen_projections(errgen, projection_type, projection_basis, mx_basis='gm', return_generators=False, return_scale_fctr=False)

Compute the projections of a gate error generator onto generators for a standard set of errors.

This standard set of errors is given by projection_type, and is constructed from the elements of the projection_basis basis.

Parameters
• errgen (: ndarray) – The error generator matrix to project.

• projection_type ({"hamiltonian", "stochastic", "affine"}) – The type of error generators to project the gate error generator onto. If “hamiltonian”, then use the Hamiltonian generators which take a density matrix rho -> -i*[ H, rho ] for Pauli-product matrix H. If “stochastic”, then use the Stochastic error generators which take rho -> P*rho*P for Pauli-product matrix P (recall P is self adjoint). If “affine”, then use the affine error generators which take rho -> P (superop is |P>><<1|).

• projection_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• return_generators (bool, optional) – If True, return the error generators projected against along with the projection values themseves.

• return_scale_fctr (bool, optional) – If True, also return the scaling factor that was used to multply the projections onto normalized error generators to get the returned values.

Returns

• projections (numpy.ndarray) – An array of length equal to the number of elements in the basis used to construct the projectors. Typically this is is also the dimension of the gate (e.g. 4 for a single qubit).

• generators (numpy.ndarray) – Only returned when return_generators == True. An array of shape (#basis-els,op_dim,op_dim) such that generators[i] is the generator corresponding to the i-th basis element. Note that these matricies are in the std (matrix unit) basis.

• scale (float) – Only returned when return_scale_fctr == True. A mulitplicative scaling constant that has already been applied to projections.

pygsti.tools.optools._assert_shape(ar, shape, sparse=False)

Asserts ar.shape == shape ; works with sparse matrices too

pygsti.tools.optools.lindblad_error_generator(errorgen_type, basis_element_labels, basis_1q, normalize, sparse=False, tensorprod_basis=False)

TODO: docstring - labels can be, e.g. (‘H’, ‘XX’) and basis should be a 1-qubit basis w/single-char labels

Compute the superoperator-generators corresponding to Lindblad terms.

This routine computes the Hamiltonian and Non-Hamiltonian (“other”) superoperator generators which correspond to the terms of the Lindblad expression:

L(rho) = sum_i( h_i [A_i,rho] ) +
sum_ij( o_ij * (B_i rho B_j^dag -

0.5( rho B_j^dag B_i + B_j^dag B_i rho) ) )

where {A_i} and {B_i} are bases (possibly the same) for Hilbert Schmidt (density matrix) space with the identity element removed so that each A_i and B_i are traceless. If we write L(rho) in terms of superoperators H_i and O_ij,

L(rho) = sum_i( h_i H_i(rho) ) + sum_ij( o_ij O_ij(rho) )

then this function computes the matrices for H_i and O_ij using the given density matrix basis. Thus, if dmbasis is expressed in the standard basis (as it should be), the returned matrices are also in this basis.

If these elements are used as projectors it may be usedful to normalize them (by setting normalize=True). Note, however, that these projectors are not all orthogonal - in particular the O_ij’s are not orthogonal to one another.

Parameters
• dmbasis_ham (list) – A list of basis matrices {B_i} including the identity as the first element, for the returned Hamiltonian-type error generators. This argument is easily obtained by call to pp_matrices() or a similar function. The matrices are expected to be in the standard basis, and should be traceless except for the identity. Matrices should be NumPy arrays or SciPy CSR sparse matrices.

• dmbasis_other (list) – A list of basis matrices {B_i} including the identity as the first element, for the returned Stochastic-type error generators. This argument is easily obtained by call to pp_matrices() or a similar function. The matrices are expected to be in the standard basis, and should be traceless except for the identity. Matrices should be NumPy arrays or SciPy CSR sparse matrices.

• normalize (bool) – Whether or not generators should be normalized so that numpy.linalg.norm(generator.flat) == 1.0 Note that the generators will still, in general, be non-orthogonal.

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian Lindblad error generators to construct. Allowed values are: “diagonal” (only the diagonal Stochastic generators are returned; that is, the generators corresponding to the i==j terms in the Lindblad expression.), “diag_affine” (diagonal + affine generators), and “all” (all generators).

Returns

• ham_generators (numpy.ndarray or list of SciPy CSR matrices) – If dense matrices where given, an array of shape (d-1,d,d), where d is the size of the basis, i.e. d == len(dmbasis). ham_generators[i] gives the matrix for H_i. If sparse matrices were given, a list of shape (d,d) CSR matrices.

• other_generators (numpy.ndarray or list of lists of SciPy CSR matrices) – If dense matrices where given, An array of shape (d-1,d-1,d,d), (2,d-1,d,d), or (d-1,d,d), where d is the size of the basis, for other_mode equal to “all”, “diag_affine”, or “diagonal”, respectively. For instance, in the “all” case, other_generators[i,j] gives the matrix for O_ij. If sparse matrices were given, the all but the final 2 dimensions are lists (e.g. the “all” case returns a list of lists of shape (d,d) CSR matrices).

pygsti.tools.optools.lindblad_errorgen_projections(errgen, ham_basis, other_basis, mx_basis='gm', normalize=True, return_generators=False, other_mode='all', sparse=False)

Compute the projections of an error generator onto generators for the Lindblad-term errors.

Note that these Lindblad-term errors are expressed in given bases.

Parameters
• errgen (: ndarray) – The error generator matrix to project.

• ham_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct the Hamiltonian-type lindblad error Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• other_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct the Stochastic-type lindblad error Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source basis. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

• normalize (bool, optional) – Whether or not the generators being projected onto are normalized, so that numpy.linalg.norm(generator.flat) == 1.0. Note that the generators will still, in general, be non-orthogonal.

• return_generators (bool, optional) – If True, return the error generators projected against along with the projection values themseves.

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian Lindblad error projections to obtain. Allowed values are: “diagonal” (only the diagonal Stochastic), “diag_affine” (diagonal + affine generators), and “all” (all generators).

• sparse (bool, optional) – Whether to create sparse or dense basis matrices when strings are given as ham_basis and other_basis

Returns

• ham_projections (numpy.ndarray) – An array of length d-1, where d is the dimension of the gate, giving the projections onto the Hamiltonian-type Lindblad terms.

• other_projections (numpy.ndarray) – An array of shape (d-1,d-1), (2,d-1), or (d-1,), where d is the dimension of the gate, for other_mode equal to “all”, “diag_affine”, or “diagonal”, respectively. Values give the projections onto the non-Hamiltonian-type Lindblad terms.

• ham_generators (numpy.ndarray) – The Hamiltonian-type Lindblad term generators, as would be returned from lindblad_error_generators(pp_matrices(sqrt(d)), normalize). Shape is (d-1,d,d), and ham_generators[i] is in the standard basis.

• other_generators (numpy.ndarray) – The Stochastic-type Lindblad term generators, as would be returned from lindblad_error_generators(pp_matrices(sqrt(d)), normalize). Shape is (d-1,d-1,d,d), (2,d-1,d,d), or (d-1,d,d) for other_mode equal to “all”, “diag_affine”, or “diagonal”, respectively, and other_generators[i] is in the std basis.

pygsti.tools.optools.projections_to_lindblad_terms(ham_projs, other_projs, ham_basis, other_basis, other_mode='all', return_basis=True)

Converts error-generator projections into a dictionary of error coefficients.

Converts the projections of an error generator onto basis elements into a Lindblad-term dictionary and basis used to individually specify Lindblad terms.

Parameters
• ham_projs (numpy.ndarray) – An array of length d-1, where d is the dimension of the projected error generator, giving the projections onto the Hamiltonian-type Lindblad terms.

• other_projs (numpy.ndarray) – An array of shape (d-1,d-1), (2,d-1), or (d-1,), where d is the dimension of the projected error generator, for other_mode equal to “all”, “diag_affine”, or “diagonal”, respectively. Values give the projections onto the non-Hamiltonian-type Lindblad terms.

• ham_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct ham_projs. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• other_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct other_projs. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian Lindblad error projections other_projs includes. Allowed values are: “diagonal” (only the diagonal Stochastic), “diag_affine” (diagonal + affine generators), and “all” (all generators).

• return_basis (bool, optional) – Whether to return a Basis containing the elements corresponding to labels within the returned Ltermdict.

Returns

• Ltermdict (dict) – Keys are (termType, basisLabel1, <basisLabel2>) tuples, where termType is “H” (Hamiltonian), “S” (Stochastic), or “A” (Affine). Hamiltonian and Affine terms always have a single basis label (so key is a 2-tuple) whereas Stochastic tuples have 1 basis label to indicate a diagonal term and otherwise have 2 basis labels to specify off-diagonal non-Hamiltonian Lindblad terms. Basis labels are taken from ham_basis and other_basis. Values are complex coefficients (the projections).

• basis (Basis) – A single basis containing all the basis labels used in Ltermdict (and only those elements). Only returned when return_basis == True.

Convert a set of Lindblad terms into a dense matrix/grid of projections.

Parameters
• lindblad_term_dict (dict) – A dictionary specifying which Linblad terms are present in the gate parameteriztion. Keys are (termType, basisLabel1, <basisLabel2>) tuples, where termType is “H” (Hamiltonian), “S” (Stochastic), or “A” (Affine). Hamiltonian and Affine terms always have a single basis label (so key is a 2-tuple) whereas Stochastic tuples with 1 basis label indicate a diagonal term, and are the only types of terms allowed when nonham_mode != “all”. Otherwise, Stochastic term tuples can include 2 basis labels to specify “off-diagonal” non-Hamiltonian Lindblad terms. Basis labels can be strings or integers. Values are complex coefficients (error rates).

• basis (Basis) – A basis mapping the labels used in the keys of lindblad_term_dict to basis matrices (e.g. numpy arrays or Scipy sparse matrices). The first element of this basis should be an identity element, and will be propagated to the returned ham_basis and other_basis.

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian terms are allowed in lindblad_term_dict. Allowed values are: “diagonal” (only the diagonal Stochastic), “diag_affine” (diagonal + affine generators), and “all” (all generators).

Returns

• hamProjs (numpy.ndarray) – An array of length basisdim-1, giving the projections onto a full set of the Hamiltonian-type Lindblad terms (onto each element of ham_basis).

• otherProjs (numpy.ndarray) – An array of shape (d-1,d-1), (2,d-1), or (d-1,), where d=`basisdim` for other_mode equal to “all”, “diag_affine”, or “diagonal”, respectively. Values give the projections onto the non-Hamiltonian -type Lindblad terms.

• ham_basis (Basis) – The basis used to construct hamProjs.

• other_basis (Basis) – The basis used to construct otherProjs.

• hamBasisIndices (OrderedDict) – A dictionary mapping the some or all of the basis labels of basisdict to the integers 0 to len(ham_basis). These are indices into hamProjs, giving the projection associated with each Hamiltonian basis element.

• otherBasisIndices (OrderedDict) – A dictionary mapping the some or all of the basis labels of basisdict to the integers 0 to len(other_basis). These are row and column indices into otherProjs, giving the projection associated with each pair of “other” basis elements (or single basis element if other_mode!=”all”).

Computes labels corresponding to the parameters obtained via calls to :function:`lindblad_errorgen_projections` and then :function:`lindblad_projections_to_paramvals`. The arguments to this function must match those given to the above (where they overlap).

Parameters
• ham_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct the Hamiltonian-type lindblad error Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• other_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct the Stochastic-type lindblad error Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• param_mode ({"unconstrained", "cptp", "depol", "reldepol"}) – Describes how values in ham_projs and otherProj relate to the returned parameter values. Allowed values are: “unconstrained” (projs are independent unconstrained parameters), “cptp” (independent parameters but constrained so map is CPTP), “reldepol” (all non-Ham. diagonal projs take the same value), “depol” (same as “reldepol” but projs must be positive)

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian Lindblad error projections other_projs includes. Allowed values are: “diagonal” (only the diagonal Stochastic), “diag_affine” (diagonal + affine generators), and “all”.

• dim (int, optional) – The dimension of the error generator matrix, used if the bases are given as strings.

Returns

param_labels (list) – A list of strings that describe each parameter.

Compute Lindblad-gate parameter values from error generator projections.

Constructs an array of paramter values from the separate arrays of Hamiltonian and non-Hamiltonian Lindblad-term projections.

When cptp=True, this function handles parameterizing the projections to that for (real) parameter values correspond to projections for a valid CPTP gate (e.g. by parameterizing the Cholesky decomposition of other_projs instead of other_projs itself). This function is closely related to implementation details of the LindbladOp class.

Parameters
• ham_projs (numpy.ndarray) – An array of length d-1, where d is the gate dimension, giving the projections onto a full set of the Hamiltonian-type Lindblad terms.

• other_projs (numpy.ndarray) – An array of shape (d-1,d-1), (2,d-1), or (d-1,), where d is the gate dimension, for other_mode equal to “all”,`”diag_affine”, or `”diagonal”, respectively. Values give the projections onto a full set of non-Hamiltonian-type Lindblad terms.

• param_mode ({"unconstrained", "cptp", "depol", "reldepol"}) – Describes how values in ham_projs and otherProj relate to the returned parameter values. Allowed values are: “unconstrained” (projs are independent unconstrained parameters), “cptp” (independent parameters but constrained so map is CPTP), “reldepol” (all non-Ham. diagonal projs take the same value), “depol” (same as “reldepol” but projs must be positive)

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian Lindblad error projections other_projs includes. Allowed values are: “diagonal” (only the diagonal Stochastic), “diag_affine” (diagonal + affine generators), and “all”.

• truncate (bool or float, optional) – Whether to truncate the projections onto the Lindblad terms in order to meet constraints (e.g. to preserve CPTP) when necessary. If >= 0 or False, then an error is thrown when the given projections cannot be parameterized as specified, using the value given as the the maximum negative eigenvalue that is tolerated (False is equivalent to 1e-12). True tolerates any negative eigenvalues.

Returns

param_vals (numpy.ndarray) – A 1D array of real parameter values consisting of d-1 Hamiltonian values followed by either (d-1)^2, 2*(d-1), or just d-1 non-Hamiltonian values for other_mode equal to “all”, “diag_affine”, or “diagonal”, respectively.

Constructs a dictionary mapping Lindblad term labels to projection coefficients.

This method is used for finding the index of a particular error generator coefficient in the 1D array formed by concatenating the Hamiltonian and flattened stochastic projection arrays.

Parameters
• ham_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct ham_projs. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• other_basis ({'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object) – The basis used to construct other_projs. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt), list of numpy arrays, or a custom basis object.

• other_mode ({"diagonal", "diag_affine", "all"}) – Which non-Hamiltonian Lindblad error projections other_projs includes. Allowed values are: “diagonal” (only the diagonal Stochastic), “diag_affine” (diagonal + affine generators), and “all” (all generators).

Returns

Ltermdict (dict) – Keys are (termType, basisLabel1, <basisLabel2>) tuples, where termType is “H” (Hamiltonian), “S” (Stochastic), or “A” (Affine). Hamiltonian and Affine terms always have a single basis label (so key is a 2-tuple) whereas Stochastic tuples have 1 basis label to indicate a diagonal term and otherwise have 2 basis labels to specify off-diagonal non-Hamiltonian Lindblad terms. Basis labels are taken from ham_basis and other_basis. Values are integer indices.

pygsti.tools.optools.paramvals_to_lindblad_projections(paramvals, ham_basis_size, other_basis_size, param_mode='cptp', other_mode='all', cache_mx=None)

Computes the separate arrays of Hamiltonian and non-Hamiltonian Lindblad-term projections from an array of Lindblad-operator parameter values.

This function essentially performs the inverse of :function:`lindblad_projections_to_paramvals`.

Parameters
• paramvals (numpy.ndarray) – A 1D array of real parameter values consisting of d-1 Hamiltonian values followed by either (d-1)^2 or just d-1 non-Hamiltonian values (the latter when other_mode in (‘diagonal’,’diag_affine’)).

• ham_basis_size (int) – The number of elements in the Hamiltonian basis used to construct paramvals. As such, ham_basis_size gives the offset into paramvals where the non-Hamiltonian parameters begin.

• other_basis_size (int) – The number of elements in the non-Hamiltonian basis used to construct paramvals.

• param_mode ({"unconstrained", "cptp", "depol", "reldepol"}) – Specifies how the Lindblad-term coefficients are mapped to the set of (real) parameter values. This really just applies to the “other” (non-Hamiltonian) coefficients. “unconstrained” means that ranging over the parameter values lets the coefficient-matrix vary over all matrices, “cptp” restricts this to postitive matrices. “depol” maps all of the coefficients to the same, positive parameter (only available for “diagonal” and “diag_affine” other-modes), and “reldepol” does the same thing but without the positivity constraint.

• other_mode ({"all", "diagonal", "diag_affine"}) – Specifies the structure of the matrix of other (non-Hamiltonian) coefficients. If d is the gate dimension, “all” means a (d-1,d-1) matrix is used; “diagonal” means just the (d2-1,) diagonal of this matrix is used; “diag_affine” means the coefficients are in a (2,d2-1) array with the diagonal-term coefficients being the first row and the affine coefficients being the second row.

• cache_mx (ndarray, optional) – Scratch space that is used to store the lower-triangular Cholesky decomposition matrix that is used to construct the “other” projections when there is a CPTP constraint.

Returns

• ham_projs (numpy.ndarray) – An array of length d-1, where d is the gate dimension, giving the projections onto a full set of the Hamiltonian-type Lindblad terms.

• other_projs (numpy.ndarray) – An array of shape (d-1,d-1) or (d-1,) or (2,d-1) where d is the gate dimension, giving the projections onto a full set of non-Hamiltonian -type Lindblad terms (see other_mode above).

pygsti.tools.optools.paramvals_to_lindblad_projections_deriv(paramvals, ham_basis_size, other_basis_size, param_mode='cptp', other_mode='all', cache_mx=None)

Construct derivative of Lindblad-term projections with respect to the parameter values.

Computes separate derivative arrays of Hamiltonian and non-Hamiltonian Lindblad-term projections from an array of Lindblad-operator parameter values.

This function gives the Jacobian of what is returned by :function:`paramvals_to_lindblad_projections` (as a function of the parameters).

Parameters
• paramvals (numpy.ndarray) – A 1D array of real parameter values consisting of d-1 Hamiltonian values followed by either (d-1)^2 or just d-1 non-Hamiltonian values (the latter when other_mode in (‘diagonal’,’diag_affine’)).

• ham_basis_size (int) – The number of elements in the Hamiltonian basis used to construct paramvals. As such, ham_basis_size gives the offset into paramvals where the non-Hamiltonian parameters begin.

• other_basis_size (int) – The number of elements in the non-Hamiltonian basis used to construct paramvals.

• param_mode ({"unconstrained", "cptp", "depol", "reldepol"}) – Specifies how the Lindblad-term coefficients are mapped to the set of (real) parameter values. This really just applies to the “other” (non-Hamiltonian) coefficients. “unconstrained” means that ranging over the parameter values lets the coefficient-matrix vary over all matrices, “cptp” restricts this to postitive matrices. “depol” maps all of the coefficients to the same, positive parameter (only available for “diagonal” and “diag_affine” other-modes), and “reldepol” does the same thing but without the positivity constraint.

• other_mode ({"all", "diagonal", "diag_affine"}) – Specifies the structure of the matrix of other (non-Hamiltonian) coefficients. If d is the gate dimension, “all” means a (d-1,d-1) matrix is used; “diagonal” means just the (d2-1,) diagonal of this matrix is used; “diag_affine” means the coefficients are in a (2,d2-1) array with the diagonal-term coefficients being the first row and the affine coefficients being the second row.

• cache_mx (ndarray, optional) – Scratch space that is used to store the lower-triangular Cholesky decomposition matrix that is used to construct the “other” projections when there is a CPTP constraint.

Returns

• ham_projs_deriv (numpy.ndarray) – A real array of shape (d-1,nP), where d is the Hamiltonian basis size and nP is the number of parameters (the length of paramvals).

• other_projs_deriv (numpy.ndarray) – An array of shape (d-1,d-1,nP) or (d-1,nP) or (2,d-1,nP) where d is the size of the “other” basis and nP is the number of parameters (the length of paramvals). In the first case, when param_mode is “unconstrained” or “cptp”, the array is complex, otherwise it is real.

pygsti.tools.optools.rotation_gate_mx(r, mx_basis='gm')

Construct a rotation operation matrix.

Build the operation matrix corresponding to the unitary

exp(-i * (r/2*PP*sqrt(d) + r/2*PP*sqrt(d) + …) )

where PP’ is the array of Pauli-product matrices obtained via `pp_matrices(d), where d = sqrt(len(r)+1). The division by 2 is for convention, and the sqrt(d) is to essentially un-normalise the matrices returned by :function:`pp_matrices` to they are equal to products of the standard Pauli matrices.

Parameters
• r (tuple) – A tuple of coeffiecients, one per non-identity Pauli-product basis element

• mx_basis ({'std', 'gm', 'pp', 'qt'} or Basis object) – The source and destination basis, respectively. Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom basis object).

Returns

numpy array – a d^2 x d^2 operation matrix in the specified basis.

pygsti.tools.optools.project_model(model, target_model, projectiontypes=('H', 'S', 'H+S', 'LND'), gen_type='logG-logT', logG_weight=None)

Construct a new model(s) by projecting the error generator of model onto some sub-space then reconstructing.

Parameters
• model (Model) – The model whose error generator should be projected.

• target_model (Model) – The set of target (ideal) gates.

• projectiontypes (tuple of {'H','S','H+S','LND','LNDF'}) –

Which projections to use. The length of this tuple gives the number of Model objects returned. Allowed values are:

• ’H’ = Hamiltonian errors

• ’S’ = Stochastic Pauli-channel errors

• ’H+S’ = both of the above error types

• ’LND’ = errgen projected to a normal (CPTP) Lindbladian

• ’LNDF’ = errgen projected to an unrestricted (full) Lindbladian

• gen_type ({"logG-logT", "logTiG", "logGTi"}) – The type of error generator to compute. For more details, see func:error_generator.

• logG_weight (float or None (default)) – Regularization weight for approximate logG in logG-logT generator. For more details, see func:error_generator.

Returns

• projected_models (list of Models) – Elements are projected versions of model corresponding to the elements of projectiontypes.

• Nps (list of parameter counts) – Integer parameter counts for each model in projected_models. Useful for computing the expected log-likelihood or chi2.

pygsti.tools.optools.compute_best_case_gauge_transform(gate_mx, target_gate_mx, return_all=False)

Returns a gauge transformation that maps gate_mx into a matrix that is co-diagonal with target_gate_mx.

(Co-diagonal means that they share a common set of eigenvectors.)

Gauge transformations effectively change the basis of all the gates in a model. From the perspective of a single gate a gauge transformation leaves it’s eigenvalues the same and changes its eigenvectors. This function finds a real transformation that transforms the eigenspaces of gate_mx so that there exists a set of eigenvectors which diagonalize both gate_mx and target_gate_mx.

Parameters
• gate_mx (numpy.ndarray) – Gate matrix to transform.

• target_gate_mx (numpy.ndarray) – Target gate matrix.

• return_all (bool, optional) – If true, also return the matrices of eigenvectors for Ugate for gate_mx and Utgt for target_gate_mx such that U = dot(Utgt, inv(Ugate)) is real.

Returns

• U (numpy.ndarray) – A gauge transformation such that if epgate = U * gate_mx * U_inv, then epgate (which has the same eigenalues as gate_mx), can be diagonalized with a set of eigenvectors that also diagonalize target_gate_mx. Furthermore, U is real.

• Ugate, Utgt (numpy.ndarray) – only if return_all == True. See above.

pygsti.tools.optools.project_to_target_eigenspace(model, target_model, eps=1e-06)

Project each gate of model onto the eigenspace of the corresponding gate within target_model.

Returns the resulting Model.

Parameters
• model (Model) – Model to act on.

• target_model (Model) – The target model, whose gates define the target eigenspaces being projected onto.

• eps (float, optional) – Small magnitude specifying how much to “nudge” the target gates before eigen-decomposing them, so that their spectra will have the same conjugacy structure as the gates of model.

Returns

Model

pygsti.tools.optools.unitary_to_pauligate(u)

Get the linear operator on (vectorized) density matrices corresponding to a n-qubit unitary operator on states.

Parameters

u (numpy array) – A dxd array giving the action of the unitary on a state in the sigma-z basis. where d = 2 ** n-qubits

Returns

numpy array – The operator on density matrices that have been vectorized as d**2 vectors in the Pauli basis.

Whether typ is a recognized Lindblad-gate parameterization type.

A Lindblad type is comprised of a parameter specification followed optionally by an evolution-type suffix. The parameter spec can be “GLND” (general unconstrained Lindbladian), “CPTP” (cptp-constrained), or any/all of the letters “H” (Hamiltonian), “S” (Stochastic, CPTP), “s” (Stochastic), “A” (Affine), “D” (Depolarization, CPTP), “d” (Depolarization) joined with plus (+) signs. Note that “A” cannot appear without one of {“S”,”s”,”D”,”d”}. The suffix can be non-existent (density-matrix), “terms” (state-vector terms) or “clifford terms” (stabilizer-state terms). For example, valid Lindblad types are “H+S”, “H+d+A”, “CPTP clifford terms”, or “S+A terms”.

Parameters

typ (str) – A paramterization type.

Returns

bool

pygsti.tools.optools.effect_label_to_outcome(povm_and_effect_lbl)

Extract the outcome label from a “simplified” effect label.

Simplified effect labels are not themselves so simple. They combine POVM and effect labels so that accessing any given effect vector is simpler.

If povm_and_effect_lbl is None then “NONE” is returned.

Parameters

povm_and_effect_lbl (Label) – Simplified effect vector.

Returns

str

pygsti.tools.optools.effect_label_to_povm(povm_and_effect_lbl)

Extract the POVM label from a “simplified” effect label.

Simplified effect labels are not themselves so simple. They combine POVM and effect labels so that accessing any given effect vector is simpler.

If povm_and_effect_lbl is None then “NONE” is returned.

Parameters

povm_and_effect_lbl (Label) – Simplified effect vector.

Returns

str