Skip to content

Commit

Permalink
check in
Browse files Browse the repository at this point in the history
rileyjmurray committed May 23, 2024
1 parent 55da605 commit f82655a
Showing 10 changed files with 31 additions and 787 deletions.
7 changes: 7 additions & 0 deletions pygsti/extras/interpygate/__init__.py
Original file line number Diff line number Diff line change
@@ -10,3 +10,10 @@

from .core import PhysicalProcess, InterpolatedDenseOp, InterpolatedOpFactory
from .process_tomography import vec, unvec, run_process_tomography

# Note from Riley on May 22, 2024:
#
# I wanted to remove the implementations of vec and unvec and just in-line equivalent
# code in the few places they were used. However, the fact that they're included in this
# __init__.py file suggests that they might be used outside of pyGSTi itself.
#
8 changes: 4 additions & 4 deletions pygsti/extras/interpygate/process_tomography.py
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ def vec(matrix):
"""
matrix = _np.array(matrix)
if matrix.shape == (len(matrix), len(matrix)):
return _np.array([_np.concatenate(_np.array(matrix).T)]).T
return matrix.reshape((-1, 1), order='F')
else:
raise ValueError('The input matrix must be square.')

@@ -50,9 +50,9 @@ def unvec(vectorized):
"""
vectorized = _np.array(vectorized)
length = int(_np.sqrt(max(vectorized.shape)))
if len(vectorized) == length ** 2:
return _np.reshape(vectorized, [length, length]).T
dim = int(_np.sqrt(max(vectorized.shape)))
if len(vectorized) == dim ** 2:
return vectorized.reshape((dim, dim), order='F')
else:
raise ValueError(
'The input vector length must be a perfect square, but this input has length %d.' % len(vectorized))
135 changes: 1 addition & 134 deletions pygsti/modelmembers/operations/lindbladerrorgen.py
Original file line number Diff line number Diff line change
@@ -497,140 +497,7 @@ def __init__(self, lindblad_coefficient_blocks, lindblad_basis='auto', mx_basis=
self._paramlbls = _np.array(list(_itertools.chain.from_iterable(
[blk.param_labels for blk in self.coefficient_blocks])), dtype=object)
assert(self._onenorm_upbound is not None) # _update_rep should set this
#Done with __init__(...)

#def _init_generators(self, dim):
# #assumes self.dim, self.ham_basis, self.other_basis, and self.matrix_basis are setup...
# sparse_bases = bool(self._rep_type == 'sparse superop')
#
# #HERE TODO - need to update this / MOVE to block class?
# #use caching to increase performance - cache based on all the self.XXX members utilized by this fn
# cache_key = (self._rep_type, self.matrix_basis, self.ham_basis, self.other_basis, self.parameterization)
# #print("cache key = ",self._rep_type, (self.matrix_basis.name, self.matrix_basis.dim),
# # (self.ham_basis.name, self.ham_basis.dim), (self.other_basis.name, self.other_basis.dim),
# # str(self.parameterization))
#
# if cache_key not in self._generators_cache:
#
# d = int(round(_np.sqrt(dim)))
# assert(d * d == dim), "Errorgen dim must be a perfect square"
#
# # Get basis transfer matrix
# mxBasisToStd = self.matrix_basis.create_transform_matrix(
# _BuiltinBasis("std", self.matrix_basis.dim, sparse_bases))
# # use BuiltinBasis("std") instead of just "std" in case matrix_basis is a TensorProdBasis
# leftTrans = _spsl.inv(mxBasisToStd.tocsc()).tocsr() if _sps.issparse(mxBasisToStd) \
# else _np.linalg.inv(mxBasisToStd)
# rightTrans = mxBasisToStd
#
# hamBasisMxs = self.ham_basis.elements
# otherBasisMxs = self.other_basis.elements
#
# hamGens, otherGens = _ot.lindblad_error_generators(
# hamBasisMxs, otherBasisMxs, normalize=False,
# other_mode=self.parameterization.nonham_mode) # in std basis
#
# # Note: lindblad_error_generators will return sparse generators when
# # given a sparse basis (or basis matrices)
#
# if hamGens is not None:
# bsH = len(hamGens) + 1 # projection-basis size (not nec. == dim)
# _ot._assert_shape(hamGens, (bsH - 1, dim, dim), sparse_bases)
#
# # apply basis change now, so we don't need to do so repeatedly later
# if sparse_bases:
# hamGens = [_mt.safe_real(_mt.safe_dot(leftTrans, _mt.safe_dot(mx, rightTrans)),
# inplace=True, check=True) for mx in hamGens]
# for mx in hamGens: mx.sort_indices()
# # for faster addition ops in _construct_errgen_matrix
# else:
# #hamGens = _np.einsum("ik,akl,lj->aij", leftTrans, hamGens, rightTrans)
# hamGens = _np.transpose(_np.tensordot(
# _np.tensordot(leftTrans, hamGens, (1, 1)), rightTrans, (2, 0)), (1, 0, 2))
# else:
# bsH = 0
# assert(bsH == self.ham_basis_size)
#
# if otherGens is not None:
#
# if self.parameterization.nonham_mode == "diagonal":
# bsO = len(otherGens) + 1 # projection-basis size (not nec. == dim)
# _ot._assert_shape(otherGens, (bsO - 1, dim, dim), sparse_bases)
#
# # apply basis change now, so we don't need to do so repeatedly later
# if sparse_bases:
# otherGens = [_mt.safe_real(_mt.safe_dot(leftTrans, _mt.safe_dot(mx, rightTrans)),
# inplace=True, check=True) for mx in otherGens]
# for mx in otherGens: mx.sort_indices()
# # for faster addition ops in _construct_errgen_matrix
# else:
# #otherGens = _np.einsum("ik,akl,lj->aij", leftTrans, otherGens, rightTrans)
# otherGens = _np.transpose(_np.tensordot(
# _np.tensordot(leftTrans, otherGens, (1, 1)), rightTrans, (2, 0)), (1, 0, 2))
#
# elif self.parameterization.nonham_mode == "diag_affine":
# # projection-basis size (not nec. == dim) [~shape[1] but works for lists too]
# bsO = len(otherGens[0]) + 1
# _ot._assert_shape(otherGens, (2, bsO - 1, dim, dim), sparse_bases)
#
# # apply basis change now, so we don't need to do so repeatedly later
# if sparse_bases:
# otherGens = [[_mt.safe_dot(leftTrans, _mt.safe_dot(mx, rightTrans))
# for mx in mxRow] for mxRow in otherGens]
#
# for mxRow in otherGens:
# for mx in mxRow: mx.sort_indices()
# # for faster addition ops in _construct_errgen_matrix
# else:
# #otherGens = _np.einsum("ik,abkl,lj->abij", leftTrans,
# # otherGens, rightTrans)
# otherGens = _np.transpose(_np.tensordot(
# _np.tensordot(leftTrans, otherGens, (1, 2)), rightTrans, (3, 0)), (1, 2, 0, 3))
#
# else:
# bsO = len(otherGens) + 1 # projection-basis size (not nec. == dim)
# _ot._assert_shape(otherGens, (bsO - 1, bsO - 1, dim, dim), sparse_bases)
#
# # apply basis change now, so we don't need to do so repeatedly later
# if sparse_bases:
# otherGens = [[_mt.safe_dot(leftTrans, _mt.safe_dot(mx, rightTrans))
# for mx in mxRow] for mxRow in otherGens]
# #Note: complex OK here, as only linear combos of otherGens (like (i,j) + (j,i)
# # terms) need to be real
#
# for mxRow in otherGens:
# for mx in mxRow: mx.sort_indices()
# # for faster addition ops in _construct_errgen_matrix
# else:
# #otherGens = _np.einsum("ik,abkl,lj->abij", leftTrans,
# # otherGens, rightTrans)
# otherGens = _np.transpose(_np.tensordot(
# _np.tensordot(leftTrans, otherGens, (1, 2)), rightTrans, (3, 0)), (1, 2, 0, 3))
#
# else:
# bsO = 0
# assert(bsO == self.other_basis_size)
#
# if hamGens is not None:
# hamGens_1norms = _np.array([_mt.safe_onenorm(mx) for mx in hamGens], 'd')
# else:
# hamGens_1norms = None
#
# if otherGens is not None:
# if self.parameterization.nonham_mode == "diagonal":
# otherGens_1norms = _np.array([_mt.safe_onenorm(mx) for mx in otherGens], 'd')
# else:
# otherGens_1norms = _np.array([_mt.safe_onenorm(mx)
# for oGenRow in otherGens for mx in oGenRow], 'd')
# else:
# otherGens_1norms = None
#
# self._generators_cache[cache_key] = (hamGens, otherGens, hamGens_1norms, otherGens_1norms)
#
# cached_hamGens, cached_otherGens, cached_h1norms, cached_o1norms = self._generators_cache[cache_key]
# return (_copy.deepcopy(cached_hamGens), _copy.deepcopy(cached_otherGens),
# cached_h1norms.copy() if (cached_h1norms is not None) else None,
# cached_o1norms.copy() if (cached_o1norms is not None) else None)
# Done with __init__(...)

def _init_terms(self, coefficient_blocks, max_polynomial_vars):

317 changes: 0 additions & 317 deletions pygsti/modelmembers/povms/composedeffect.py

Large diffs are not rendered by default.

317 changes: 0 additions & 317 deletions pygsti/modelmembers/states/composedstate.py

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion pygsti/models/fogistore.py
Original file line number Diff line number Diff line change
@@ -547,7 +547,8 @@ def create_fogi_aggregate_single_op_space(self, op_label, errorgen_type='H',
else:
raise ValueError("Invalid intrinsic_or_relational value: `%s`" % str(intrinsic_or_relational))

space = _mt.remove_dependent_cols(space)
col_indices = _mt.independent_columns(space)
space = space[:, col_indices]
return space

@classmethod
3 changes: 2 additions & 1 deletion pygsti/tools/basistools.py
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ def change_basis(mx, from_basis, to_basis):
if _mt.safe_norm(ret, 'imag') > 1e-8:
raise ValueError("Array has non-zero imaginary part (%g) after basis change (%s to %s)!\n%s" %
(_mt.safe_norm(ret, 'imag'), from_basis, to_basis, ret))
return _mt.safe_real(ret)
return ret.real

#def transform_matrix(from_basis, to_basis, dim_or_block_dims=None, sparse=False):
# '''
@@ -507,6 +507,7 @@ def vec_to_stdmx(v, basis, keep_complex=False):
"""
if not isinstance(basis, _basis.Basis):
basis = _basis.BuiltinBasis(basis, len(v))
v = v.ravel()
ret = _np.zeros(basis.elshape, 'complex')
for i, mx in enumerate(basis.elements):
if keep_complex:
18 changes: 9 additions & 9 deletions pygsti/tools/matrixtools.py
Original file line number Diff line number Diff line change
@@ -251,7 +251,7 @@ def nice_nullspace(m, tol=1e-7, orthogonalize=False):
return ret


def normalize_columns(m, return_norms=False, norm_ord=None):
def normalize_columns(m, return_norms=False, ord=None):
"""
Normalizes the columns of a matrix.
@@ -264,7 +264,7 @@ def normalize_columns(m, return_norms=False, norm_ord=None):
If `True`, also return a 1D array containing the norms
of the columns (before they were normalized).
norm_ord : int or list of ints, optional
ord : int or list of ints, optional
The order of the norm. See :func:`numpy.linalg.norm`. An
array of orders can be given to specify the norm on a per-column
basis.
@@ -278,13 +278,13 @@ def normalize_columns(m, return_norms=False, norm_ord=None):
Only returned when `return_norms=True`, a 1-dimensional array
of the pre-normalization norm of each column.
"""
norms = column_norms(m, norm_ord)
norms = column_norms(m, ord)
norms[norms == 0.0] = 1.0 # avoid division of zero-column by zero
normalized_m = scale_columns(m, 1 / norms)
return (normalized_m, norms) if return_norms else normalized_m


def column_norms(m, norm_ord=None):
def column_norms(m, ord=None):
"""
Compute the norms of the columns of a matrix.
@@ -304,14 +304,14 @@ def column_norms(m, norm_ord=None):
A 1-dimensional array of the column norms (length is number of columns of `m`).
"""
if _sps.issparse(m):
ord_list = norm_ord if isinstance(norm_ord, (list, _np.ndarray)) else [norm_ord] * m.shape[1]
ord_list = ord if isinstance(ord, (list, _np.ndarray)) else [ord] * m.shape[1]
assert(len(ord_list) == m.shape[1])
norms = _np.array([_np.linalg.norm(m[:, j].toarray(), ord=o) for j, o in enumerate(ord_list)])
elif isinstance(norm_ord, (list, _np.ndarray)):
assert(len(norm_ord) == m.shape[1])
norms = _np.array([_np.linalg.norm(m[:, j], ord=o) for j, o in enumerate(norm_ord)])
elif isinstance(ord, (list, _np.ndarray)):
assert(len(ord) == m.shape[1])
norms = _np.array([_np.linalg.norm(m[:, j], ord=o) for j, o in enumerate(ord)])
else:
norms = _np.linalg.norm(m, axis=0, ord=norm_ord)
norms = _np.linalg.norm(m, axis=0, ord=ord)

return norms

5 changes: 3 additions & 2 deletions pygsti/tools/rbtheory.py
Original file line number Diff line number Diff line change
@@ -218,7 +218,8 @@ def rb_gauge(model, target_model, weights=None, mx_basis=None, eigenvector_weigh
vec_l_operator = vec_l_operator.real

vec_l_operator[abs(vec_l_operator) < 10**(-15)] = 0.
l_operator = _mtls.unvec(vec_l_operator)
dim = int(_np.sqrt(vec_l_operator.size))
l_operator = vec_l_operator.reshape((dim, dim), order='F')

return l_operator

@@ -791,7 +792,7 @@ def gate_dependence_of_errormaps(model, target_model, norm='diamond', mx_basis=N
mx_basis=mx_basis))
elif norm == '1to1':
gate_dif = error_gs.operations[gate] - error_gs.operations['Gavg']
delta.append(_optls.norm1to1(gate_dif, num_samples=1000, mx_basis=mx_basis, return_list=False))
delta.append(_optls.norm1to1(gate_dif, num_samples=1000, mx_basis=mx_basis))
else:
raise ValueError("Only diamond or 1to1 norm available.")

5 changes: 3 additions & 2 deletions test/unit/objects/test_fogi.py
Original file line number Diff line number Diff line change
@@ -170,15 +170,16 @@ def test_crosstalk_free_fogi(self):
nprefix = mdl.num_params - nfogi # reparameterization *prefixes* FOGI params with "unused" params
self.assertEqual(nprefix, 0) # because include_spam=True above

self.assertArraysAlmostEqual(mdl.fogi_errorgen_components_array(include_fogv=False, normalized_elem_gens=True),
mdl.to_vector()[nprefix:])
temp = mdl.fogi_errorgen_components_array(include_fogv=False, normalized_elem_gens=True)
self.assertArraysAlmostEqual(temp, mdl.to_vector()[nprefix:])

v = mdl.to_vector() # just test this works

# Test if from_vector works too
w = np.random.rand(mdl.num_params)
w[0:nprefix] = 0 # zero out all unused params (these can be SPAM and can't be any value?)
mdl.from_vector(w)
pass


def test_cloud_crosstalk_fogi(self):

0 comments on commit f82655a

Please sign in to comment.