pyGSTi 0.9.12__cp39-cp39-win32.whl → 0.9.13__cp39-cp39-win32.whl
Sign up to get free protection for your applications and to get access to all the features.
- pyGSTi-0.9.13.dist-info/METADATA +197 -0
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +211 -220
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/WHEEL +1 -1
- pygsti/_version.py +2 -2
- pygsti/algorithms/contract.py +1 -1
- pygsti/algorithms/core.py +62 -35
- pygsti/algorithms/fiducialpairreduction.py +95 -110
- pygsti/algorithms/fiducialselection.py +17 -8
- pygsti/algorithms/gaugeopt.py +2 -2
- pygsti/algorithms/germselection.py +87 -77
- pygsti/algorithms/mirroring.py +0 -388
- pygsti/algorithms/randomcircuit.py +165 -1333
- pygsti/algorithms/rbfit.py +0 -234
- pygsti/baseobjs/basis.py +94 -396
- pygsti/baseobjs/errorgenbasis.py +0 -132
- pygsti/baseobjs/errorgenspace.py +0 -10
- pygsti/baseobjs/label.py +52 -168
- pygsti/baseobjs/opcalc/fastopcalc.cp39-win32.pyd +0 -0
- pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
- pygsti/baseobjs/polynomial.py +13 -595
- pygsti/baseobjs/protectedarray.py +72 -132
- pygsti/baseobjs/statespace.py +1 -0
- pygsti/circuits/__init__.py +1 -1
- pygsti/circuits/circuit.py +753 -504
- pygsti/circuits/circuitconstruction.py +0 -4
- pygsti/circuits/circuitlist.py +47 -5
- pygsti/circuits/circuitparser/__init__.py +8 -8
- pygsti/circuits/circuitparser/fastcircuitparser.cp39-win32.pyd +0 -0
- pygsti/circuits/circuitstructure.py +3 -3
- pygsti/circuits/cloudcircuitconstruction.py +27 -14
- pygsti/data/datacomparator.py +4 -9
- pygsti/data/dataset.py +51 -46
- pygsti/data/hypothesistest.py +0 -7
- pygsti/drivers/bootstrap.py +0 -49
- pygsti/drivers/longsequence.py +46 -10
- pygsti/evotypes/basereps_cython.cp39-win32.pyd +0 -0
- pygsti/evotypes/chp/opreps.py +0 -61
- pygsti/evotypes/chp/statereps.py +0 -32
- pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
- pygsti/evotypes/densitymx/effectreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/densitymx/effectreps.pyx +1 -1
- pygsti/evotypes/densitymx/opreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/densitymx/opreps.pyx +2 -2
- pygsti/evotypes/densitymx/statereps.cp39-win32.pyd +0 -0
- pygsti/evotypes/densitymx/statereps.pyx +1 -1
- pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
- pygsti/evotypes/densitymx_slow/opreps.py +16 -23
- pygsti/evotypes/densitymx_slow/statereps.py +10 -3
- pygsti/evotypes/evotype.py +39 -2
- pygsti/evotypes/stabilizer/effectreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
- pygsti/evotypes/stabilizer/opreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/opreps.pyx +0 -4
- pygsti/evotypes/stabilizer/statereps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/statereps.pyx +1 -5
- pygsti/evotypes/stabilizer/termreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/termreps.pyx +0 -7
- pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
- pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
- pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
- pygsti/evotypes/statevec/effectreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/effectreps.pyx +1 -1
- pygsti/evotypes/statevec/opreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/opreps.pyx +2 -2
- pygsti/evotypes/statevec/statereps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/statereps.pyx +1 -1
- pygsti/evotypes/statevec/termreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/termreps.pyx +0 -7
- pygsti/evotypes/statevec_slow/effectreps.py +0 -3
- pygsti/evotypes/statevec_slow/opreps.py +0 -5
- pygsti/extras/__init__.py +0 -1
- pygsti/extras/drift/signal.py +1 -1
- pygsti/extras/drift/stabilityanalyzer.py +3 -1
- pygsti/extras/interpygate/__init__.py +12 -0
- pygsti/extras/interpygate/core.py +0 -36
- pygsti/extras/interpygate/process_tomography.py +44 -10
- pygsti/extras/rpe/rpeconstruction.py +0 -2
- pygsti/forwardsims/__init__.py +1 -0
- pygsti/forwardsims/forwardsim.py +50 -93
- pygsti/forwardsims/mapforwardsim.py +78 -20
- pygsti/forwardsims/mapforwardsim_calc_densitymx.cp39-win32.pyd +0 -0
- pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
- pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
- pygsti/forwardsims/matrixforwardsim.py +72 -17
- pygsti/forwardsims/termforwardsim.py +9 -111
- pygsti/forwardsims/termforwardsim_calc_stabilizer.cp39-win32.pyd +0 -0
- pygsti/forwardsims/termforwardsim_calc_statevec.cp39-win32.pyd +0 -0
- pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
- pygsti/forwardsims/torchfwdsim.py +265 -0
- pygsti/forwardsims/weakforwardsim.py +2 -2
- pygsti/io/__init__.py +1 -2
- pygsti/io/mongodb.py +0 -2
- pygsti/io/stdinput.py +6 -22
- pygsti/layouts/copalayout.py +10 -12
- pygsti/layouts/distlayout.py +0 -40
- pygsti/layouts/maplayout.py +103 -25
- pygsti/layouts/matrixlayout.py +99 -60
- pygsti/layouts/prefixtable.py +1534 -52
- pygsti/layouts/termlayout.py +1 -1
- pygsti/modelmembers/instruments/instrument.py +3 -3
- pygsti/modelmembers/instruments/tpinstrument.py +2 -2
- pygsti/modelmembers/modelmember.py +0 -17
- pygsti/modelmembers/operations/__init__.py +3 -4
- pygsti/modelmembers/operations/affineshiftop.py +206 -0
- pygsti/modelmembers/operations/composederrorgen.py +1 -1
- pygsti/modelmembers/operations/composedop.py +1 -24
- pygsti/modelmembers/operations/denseop.py +5 -5
- pygsti/modelmembers/operations/eigpdenseop.py +2 -2
- pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
- pygsti/modelmembers/operations/embeddedop.py +0 -1
- pygsti/modelmembers/operations/experrorgenop.py +5 -2
- pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
- pygsti/modelmembers/operations/fullcptpop.py +2 -2
- pygsti/modelmembers/operations/fulltpop.py +28 -6
- pygsti/modelmembers/operations/fullunitaryop.py +5 -4
- pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
- pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
- pygsti/modelmembers/operations/linearop.py +7 -27
- pygsti/modelmembers/operations/opfactory.py +1 -1
- pygsti/modelmembers/operations/repeatedop.py +1 -24
- pygsti/modelmembers/operations/staticstdop.py +1 -1
- pygsti/modelmembers/povms/__init__.py +3 -3
- pygsti/modelmembers/povms/basepovm.py +7 -36
- pygsti/modelmembers/povms/complementeffect.py +4 -9
- pygsti/modelmembers/povms/composedeffect.py +0 -320
- pygsti/modelmembers/povms/computationaleffect.py +1 -1
- pygsti/modelmembers/povms/computationalpovm.py +3 -1
- pygsti/modelmembers/povms/effect.py +3 -5
- pygsti/modelmembers/povms/marginalizedpovm.py +3 -81
- pygsti/modelmembers/povms/tppovm.py +74 -2
- pygsti/modelmembers/states/__init__.py +2 -5
- pygsti/modelmembers/states/composedstate.py +0 -317
- pygsti/modelmembers/states/computationalstate.py +3 -3
- pygsti/modelmembers/states/cptpstate.py +4 -4
- pygsti/modelmembers/states/densestate.py +10 -8
- pygsti/modelmembers/states/fullpurestate.py +0 -24
- pygsti/modelmembers/states/purestate.py +1 -1
- pygsti/modelmembers/states/state.py +5 -6
- pygsti/modelmembers/states/tpstate.py +28 -10
- pygsti/modelmembers/term.py +3 -6
- pygsti/modelmembers/torchable.py +50 -0
- pygsti/modelpacks/_modelpack.py +1 -1
- pygsti/modelpacks/smq1Q_ZN.py +3 -1
- pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
- pygsti/modelpacks/smq2Q_XY.py +3 -3
- pygsti/modelpacks/smq2Q_XYI.py +2 -2
- pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
- pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
- pygsti/modelpacks/smq2Q_XYXX.py +1 -1
- pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
- pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
- pygsti/modelpacks/stdtarget.py +0 -121
- pygsti/models/cloudnoisemodel.py +1 -2
- pygsti/models/explicitcalc.py +3 -3
- pygsti/models/explicitmodel.py +3 -13
- pygsti/models/fogistore.py +5 -3
- pygsti/models/localnoisemodel.py +1 -2
- pygsti/models/memberdict.py +0 -12
- pygsti/models/model.py +801 -68
- pygsti/models/modelconstruction.py +4 -4
- pygsti/models/modelnoise.py +2 -2
- pygsti/models/modelparaminterposer.py +1 -1
- pygsti/models/oplessmodel.py +1 -1
- pygsti/models/qutrit.py +15 -14
- pygsti/objectivefns/objectivefns.py +75 -140
- pygsti/objectivefns/wildcardbudget.py +2 -7
- pygsti/optimize/__init__.py +1 -0
- pygsti/optimize/arraysinterface.py +28 -0
- pygsti/optimize/customcg.py +0 -12
- pygsti/optimize/customlm.py +129 -323
- pygsti/optimize/customsolve.py +2 -2
- pygsti/optimize/optimize.py +0 -84
- pygsti/optimize/simplerlm.py +841 -0
- pygsti/optimize/wildcardopt.py +19 -598
- pygsti/protocols/confidenceregionfactory.py +28 -14
- pygsti/protocols/estimate.py +31 -14
- pygsti/protocols/gst.py +238 -142
- pygsti/protocols/modeltest.py +19 -12
- pygsti/protocols/protocol.py +9 -37
- pygsti/protocols/rb.py +450 -79
- pygsti/protocols/treenode.py +8 -2
- pygsti/protocols/vb.py +108 -206
- pygsti/protocols/vbdataframe.py +1 -1
- pygsti/report/factory.py +0 -15
- pygsti/report/fogidiagram.py +1 -17
- pygsti/report/modelfunction.py +12 -3
- pygsti/report/mpl_colormaps.py +1 -1
- pygsti/report/plothelpers.py +11 -3
- pygsti/report/report.py +16 -0
- pygsti/report/reportables.py +41 -37
- pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
- pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
- pygsti/report/workspace.py +2 -14
- pygsti/report/workspaceplots.py +328 -505
- pygsti/tools/basistools.py +9 -36
- pygsti/tools/edesigntools.py +124 -96
- pygsti/tools/fastcalc.cp39-win32.pyd +0 -0
- pygsti/tools/fastcalc.pyx +35 -81
- pygsti/tools/internalgates.py +151 -15
- pygsti/tools/jamiolkowski.py +5 -5
- pygsti/tools/lindbladtools.py +19 -11
- pygsti/tools/listtools.py +0 -114
- pygsti/tools/matrixmod2.py +1 -1
- pygsti/tools/matrixtools.py +173 -339
- pygsti/tools/nameddict.py +1 -1
- pygsti/tools/optools.py +154 -88
- pygsti/tools/pdftools.py +0 -25
- pygsti/tools/rbtheory.py +3 -320
- pygsti/tools/slicetools.py +64 -12
- pyGSTi-0.9.12.dist-info/METADATA +0 -157
- pygsti/algorithms/directx.py +0 -711
- pygsti/evotypes/qibo/__init__.py +0 -33
- pygsti/evotypes/qibo/effectreps.py +0 -78
- pygsti/evotypes/qibo/opreps.py +0 -376
- pygsti/evotypes/qibo/povmreps.py +0 -98
- pygsti/evotypes/qibo/statereps.py +0 -174
- pygsti/extras/rb/__init__.py +0 -13
- pygsti/extras/rb/benchmarker.py +0 -957
- pygsti/extras/rb/dataset.py +0 -378
- pygsti/extras/rb/io.py +0 -814
- pygsti/extras/rb/simulate.py +0 -1020
- pygsti/io/legacyio.py +0 -385
- pygsti/modelmembers/povms/denseeffect.py +0 -142
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
- {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
pygsti/tools/nameddict.py
CHANGED
@@ -88,7 +88,7 @@ class NamedDict(dict, _NicelySerializable):
|
|
88
88
|
#TODO: serialize via _to_memoized_dict once we have a base class
|
89
89
|
if x is None or isinstance(x, (float, int, str)):
|
90
90
|
return x
|
91
|
-
elif isinstance(x, _np.int64):
|
91
|
+
elif isinstance(x, (_np.int64, _np.int32)):
|
92
92
|
return int(x)
|
93
93
|
elif isinstance(x, _NicelySerializable):
|
94
94
|
return x.to_nice_serialization()
|
pygsti/tools/optools.py
CHANGED
@@ -34,28 +34,17 @@ IMAG_TOL = 1e-7 # tolerance for imaginary part being considered zero
|
|
34
34
|
def _flat_mut_blks(i, j, block_dims):
|
35
35
|
# like _mut(i,j,dim).flatten() but works with basis *blocks*
|
36
36
|
N = sum(block_dims)
|
37
|
-
mx = _np.zeros((N, N), 'd')
|
37
|
+
mx = _np.zeros((N, N), 'd')
|
38
|
+
mx[i, j] = 1.0
|
38
39
|
ret = _np.zeros(sum([d**2 for d in block_dims]), 'd')
|
39
40
|
i = 0; off = 0
|
40
41
|
for d in block_dims:
|
41
|
-
ret[i:i + d**2] = mx[off:off + d, off:off + d].
|
42
|
-
i += d**2
|
42
|
+
ret[i:i + d**2] = mx[off:off + d, off:off + d].ravel()
|
43
|
+
i += d**2
|
44
|
+
off += d
|
43
45
|
return ret
|
44
46
|
|
45
47
|
|
46
|
-
def _hack_sqrtm(a):
|
47
|
-
sqrt, _ = _spl.sqrtm(a, disp=False) # Travis found this scipy function
|
48
|
-
# to be incorrect in certain cases (we need a workaround)
|
49
|
-
if _np.any(_np.isnan(sqrt)): # this is sometimes a good fallback when sqrtm doesn't work.
|
50
|
-
ev, U = _np.linalg.eig(a)
|
51
|
-
sqrt = _np.dot(U, _np.dot(_np.diag(_np.sqrt(ev)), _np.linalg.inv(U)))
|
52
|
-
# Scipy 1.10 fix for PR 16294 (which doubles precision of complex to complex)
|
53
|
-
if _np.iscomplexobj(a):
|
54
|
-
sqrt = sqrt.astype(a.dtype, copy=False)
|
55
|
-
|
56
|
-
return sqrt
|
57
|
-
|
58
|
-
|
59
48
|
def fidelity(a, b):
|
60
49
|
"""
|
61
50
|
Returns the quantum state fidelity between density matrices.
|
@@ -81,41 +70,120 @@ def fidelity(a, b):
|
|
81
70
|
float
|
82
71
|
The resulting fidelity.
|
83
72
|
"""
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
73
|
+
__SCALAR_TOL__ = _np.finfo(a.dtype).eps ** 0.75
|
74
|
+
# ^ use for checks that have no dimensional dependence; about 1e-12 for double precision.
|
75
|
+
__VECTOR_TOL__ = (a.shape[0] ** 0.5) * __SCALAR_TOL__
|
76
|
+
# ^ use for checks that do have dimensional dependence (will naturally increase for larger matrices)
|
77
|
+
|
78
|
+
def assert_hermitian(mat):
|
79
|
+
hermiticity_error = _np.abs(mat - mat.T.conj())
|
80
|
+
if _np.any(hermiticity_error > __SCALAR_TOL__):
|
81
|
+
message = f"""
|
82
|
+
Input matrix 'mat' is not Hermitian, up to tolerance {__SCALAR_TOL__}.
|
83
|
+
The absolute values of entries in (mat - mat^H) are \n{hermiticity_error}.
|
84
|
+
"""
|
85
|
+
raise ValueError(message)
|
86
|
+
|
87
|
+
assert_hermitian(a)
|
88
|
+
assert_hermitian(b)
|
89
|
+
|
90
|
+
def check_rank_one_density(mat):
|
91
|
+
"""
|
92
|
+
mat is Hermitian of order n. This function uses an O(n^2) time randomized algorithm to
|
93
|
+
test if mat is a PSD matrix of rank 0 or 1. It returns a tuple (r, vec), where
|
94
|
+
|
95
|
+
If r == 0, then vec is the zero vector. Either mat's numerical rank is zero
|
96
|
+
OR the projection of mat onto the set of PSD matrices is zero.
|
97
|
+
|
98
|
+
If r == 1, then mat is a PSD matrix of numerical rank one, and vec is mat's
|
99
|
+
unique nontrivial eigenvector.
|
100
|
+
|
101
|
+
If r == 2, then vec is None and our best guess is that mat's (numerical) rank
|
102
|
+
is at least two. In exact arithmetic, this "guess" is correct with probability
|
103
|
+
one. Additional computations will be needed to determine if mat is PSD.
|
104
|
+
|
105
|
+
Conceptually, this function just takes a single step of the power iteration method
|
106
|
+
for estimating mat's largest eigenvalue (with size measured in absolute value).
|
107
|
+
See https://en.wikipedia.org/wiki/Power_iteration for more information.
|
108
|
+
"""
|
109
|
+
n = mat.shape[0]
|
110
|
+
|
111
|
+
if _np.linalg.norm(mat) < __VECTOR_TOL__:
|
112
|
+
# We prefer to return the zero vector instead of None to simplify how we handle
|
113
|
+
# this function's output.
|
114
|
+
return 0, _np.zeros(n, dtype=complex)
|
115
|
+
|
116
|
+
_np.random.seed(0)
|
117
|
+
test_vec = _np.random.randn(n) + 1j * _np.random.randn(n)
|
118
|
+
test_vec /= _np.linalg.norm(test_vec)
|
119
|
+
|
120
|
+
candidate_v = mat @ test_vec
|
121
|
+
candidate_v /= _np.linalg.norm(candidate_v)
|
122
|
+
alpha = _np.real(candidate_v.conj() @ mat @ candidate_v)
|
123
|
+
reconstruction = alpha * _np.outer(candidate_v, candidate_v.conj())
|
124
|
+
|
125
|
+
if _np.linalg.norm(mat - reconstruction) > __VECTOR_TOL__:
|
126
|
+
# We can't certify that mat is rank-1.
|
127
|
+
return 2, None
|
128
|
+
|
129
|
+
if alpha <= 0.0:
|
130
|
+
# Ordinarily we'd project out the negative eigenvalues and proceed with the
|
131
|
+
# PSD part of the matrix, but at this point we know that the PSD part is zero.
|
132
|
+
return 0, _np.zeros(n)
|
133
|
+
|
134
|
+
if abs(alpha - 1) > __SCALAR_TOL__:
|
135
|
+
message = f"The input matrix is not trace-1 up to tolerance {__SCALAR_TOL__}. Beware result!"
|
136
|
+
_warnings.warn(message)
|
137
|
+
candidate_v *= _np.sqrt(alpha)
|
138
|
+
|
139
|
+
return 1, candidate_v
|
140
|
+
|
141
|
+
r, vec = check_rank_one_density(a)
|
142
|
+
if r <= 1:
|
143
|
+
# special case when a is rank 1, a = vec * vec^T.
|
144
|
+
f = (vec.T.conj() @ b @ vec).real # vec^T * b * vec
|
145
|
+
return f
|
146
|
+
|
147
|
+
r, vec = check_rank_one_density(b)
|
148
|
+
if r <= 1:
|
149
|
+
# special case when b is rank 1 (recall fidelity is sym in args)
|
150
|
+
f = (vec.T.conj() @ a @ vec).real # vec^T * a * vec
|
151
|
+
return f
|
152
|
+
|
153
|
+
# Neither a nor b are rank-1. We need to actually evaluate the matrix square root of
|
154
|
+
# one of them. We do this with an eigendecomposition, since this lets us check for
|
155
|
+
# negative eigenvalues and raise a warning if needed.
|
156
|
+
|
157
|
+
def psd_square_root(mat):
|
158
|
+
evals, U = _np.linalg.eigh(mat)
|
159
|
+
if _np.min(evals) < -__SCALAR_TOL__:
|
160
|
+
message = f"""
|
161
|
+
Input matrix is not PSD up to tolerance {__SCALAR_TOL__}.
|
162
|
+
We'll project out the bad eigenspaces to only work with the PSD part.
|
163
|
+
"""
|
164
|
+
_warnings.warn(message)
|
165
|
+
evals[evals < 0] = 0.0
|
166
|
+
tr = _np.sum(evals)
|
167
|
+
if abs(tr - 1) > __VECTOR_TOL__:
|
168
|
+
message = f"""
|
169
|
+
The PSD part of the input matrix is not trace-1 up to tolerance {__VECTOR_TOL__}.
|
170
|
+
Beware result!
|
171
|
+
"""
|
172
|
+
_warnings.warn(message)
|
173
|
+
sqrt_mat = U @ (_np.sqrt(evals).reshape((-1, 1)) * U.T.conj())
|
174
|
+
return sqrt_mat
|
175
|
+
|
176
|
+
sqrt_a = psd_square_root(a)
|
177
|
+
tr_arg = psd_square_root(sqrt_a @ b @ sqrt_a)
|
178
|
+
f = _np.trace(tr_arg).real ** 2 # Tr( sqrt{ sqrt(a) * b * sqrt(a) } )^2
|
179
|
+
return f
|
110
180
|
|
111
181
|
|
112
182
|
def frobeniusdist(a, b):
|
113
183
|
"""
|
114
|
-
Returns the frobenius distance between
|
115
|
-
|
116
|
-
This is given by :
|
184
|
+
Returns the frobenius distance between arrays: ||a - b||_Fro.
|
117
185
|
|
118
|
-
|
186
|
+
This could be inlined, but we're keeping it for API consistency with other distance functions.
|
119
187
|
|
120
188
|
Parameters
|
121
189
|
----------
|
@@ -130,16 +198,14 @@ def frobeniusdist(a, b):
|
|
130
198
|
float
|
131
199
|
The resulting frobenius distance.
|
132
200
|
"""
|
133
|
-
return
|
201
|
+
return _np.linalg.norm(a - b)
|
134
202
|
|
135
203
|
|
136
204
|
def frobeniusdist_squared(a, b):
|
137
205
|
"""
|
138
|
-
Returns the square of the frobenius distance between
|
206
|
+
Returns the square of the frobenius distance between arrays: (||a - b||_Fro)^2.
|
139
207
|
|
140
|
-
This
|
141
|
-
|
142
|
-
`sum( (A_ij-B_ij)^2 )`
|
208
|
+
This could be inlined, but we're keeping it for API consistency with other distance functions.
|
143
209
|
|
144
210
|
Parameters
|
145
211
|
----------
|
@@ -154,27 +220,7 @@ def frobeniusdist_squared(a, b):
|
|
154
220
|
float
|
155
221
|
The resulting frobenius distance.
|
156
222
|
"""
|
157
|
-
return
|
158
|
-
|
159
|
-
|
160
|
-
def residuals(a, b):
|
161
|
-
"""
|
162
|
-
Calculate residuals between the elements of two matrices
|
163
|
-
|
164
|
-
Parameters
|
165
|
-
----------
|
166
|
-
a : numpy array
|
167
|
-
First matrix.
|
168
|
-
|
169
|
-
b : numpy array
|
170
|
-
Second matrix.
|
171
|
-
|
172
|
-
Returns
|
173
|
-
-------
|
174
|
-
np.array
|
175
|
-
residuals
|
176
|
-
"""
|
177
|
-
return (a - b).flatten()
|
223
|
+
return frobeniusdist(a, b)**2
|
178
224
|
|
179
225
|
|
180
226
|
def tracenorm(a):
|
@@ -402,11 +448,13 @@ def entanglement_fidelity(a, b, mx_basis='pp', is_tp=None, is_unitary=None):
|
|
402
448
|
|
403
449
|
Parameters
|
404
450
|
----------
|
405
|
-
a :
|
406
|
-
|
451
|
+
a : array or gate
|
452
|
+
The gate to compute the entanglement fidelity to b of. E.g., an
|
453
|
+
imperfect implementation of b.
|
407
454
|
|
408
|
-
b :
|
409
|
-
|
455
|
+
b : array or gate
|
456
|
+
The gate to compute the entanglement fidelity to a of. E.g., the
|
457
|
+
target gate corresponding to a.
|
410
458
|
|
411
459
|
mx_basis : {'std', 'gm', 'pp', 'qt'} or Basis object
|
412
460
|
The basis of the matrices. Allowed values are Matrix-unit (std),
|
@@ -430,6 +478,15 @@ def entanglement_fidelity(a, b, mx_basis='pp', is_tp=None, is_unitary=None):
|
|
430
478
|
-------
|
431
479
|
float
|
432
480
|
"""
|
481
|
+
from pygsti.modelmembers.operations.linearop import LinearOperator as _LinearOperator
|
482
|
+
|
483
|
+
# Attempt to cast to dense array. If this is already an array, the AttributeError
|
484
|
+
# will be suppressed.
|
485
|
+
if isinstance(a, _LinearOperator):
|
486
|
+
a = a.to_dense()
|
487
|
+
if isinstance(b, _LinearOperator):
|
488
|
+
b = b.to_dense()
|
489
|
+
|
433
490
|
d2 = a.shape[0]
|
434
491
|
|
435
492
|
#if the tp flag isn't set we'll calculate whether it is true here
|
@@ -504,6 +561,12 @@ def average_gate_fidelity(a, b, mx_basis='pp', is_tp=None, is_unitary=None):
|
|
504
561
|
AGI : float
|
505
562
|
The AGI of a to b.
|
506
563
|
"""
|
564
|
+
from pygsti.modelmembers.operations.linearop import LinearOperator as _LinearOperator
|
565
|
+
|
566
|
+
# Cast to dense to ensure we can extract the shape.
|
567
|
+
if isinstance(a, _LinearOperator):
|
568
|
+
a = a.to_dense()
|
569
|
+
|
507
570
|
d = int(round(_np.sqrt(a.shape[0])))
|
508
571
|
PF = entanglement_fidelity(a, b, mx_basis, is_tp, is_unitary)
|
509
572
|
AGF = (d * PF + 1) / (1 + d)
|
@@ -710,6 +773,12 @@ def unitarity(a, mx_basis="gm"):
|
|
710
773
|
-------
|
711
774
|
float
|
712
775
|
"""
|
776
|
+
from pygsti.modelmembers.operations.linearop import LinearOperator as _LinearOperator
|
777
|
+
|
778
|
+
# Cast to dense to ensure we can extract the shape.
|
779
|
+
if isinstance(a, _LinearOperator):
|
780
|
+
a = a.to_dense()
|
781
|
+
|
713
782
|
d = int(round(_np.sqrt(a.shape[0])))
|
714
783
|
basisMxs = _bt.basis_matrices(mx_basis, a.shape[0])
|
715
784
|
|
@@ -719,10 +788,7 @@ def unitarity(a, mx_basis="gm"):
|
|
719
788
|
B = _bt.change_basis(a, mx_basis, "gm") # everything should be able to be put in the "gm" basis
|
720
789
|
|
721
790
|
unital = B[1:d**2, 1:d**2]
|
722
|
-
|
723
|
-
#u = _np.trace(_np.dot(_np.conj(_np.transpose(unital)), unital)) / (d**2 - 1)
|
724
|
-
#new version
|
725
|
-
u= _np.einsum('ij,ji->', unital.conjugate().T, unital ) / (d**2 - 1)
|
791
|
+
u = _np.linalg.norm(unital)**2 / (d**2 - 1)
|
726
792
|
return u
|
727
793
|
|
728
794
|
|
@@ -755,7 +821,7 @@ def fidelity_upper_bound(operation_mx):
|
|
755
821
|
# # gives same result:
|
756
822
|
# closestUnitaryJmx = _np.dot(choi_evecs, _np.dot( _np.diag(new_evals), _np.linalg.inv(choi_evecs) ) )
|
757
823
|
closestJmx = _np.kron(closestVec, _np.transpose(_np.conjugate(closestVec))) # closest rank-1 Jmx
|
758
|
-
closestJmx /=
|
824
|
+
closestJmx /= _np.trace(closestJmx) # normalize so trace of Jmx == 1.0
|
759
825
|
|
760
826
|
maxF = fidelity(choi, closestJmx)
|
761
827
|
|
@@ -768,7 +834,7 @@ def fidelity_upper_bound(operation_mx):
|
|
768
834
|
# print "DEBUG choi_evals = ",choi_evals, " iMax = ",iMax
|
769
835
|
# #print "DEBUG: J = \n", closestUnitaryJmx
|
770
836
|
# print "DEBUG: eigvals(J) = ", _np.linalg.eigvals(closestJmx)
|
771
|
-
# print "DEBUG: trace(J) = ",
|
837
|
+
# print "DEBUG: trace(J) = ", _np.trace(closestJmx)
|
772
838
|
# print "DEBUG: maxF = %f, maxF_direct = %f" % (maxF, maxF_direct)
|
773
839
|
# raise ValueError("ERROR: maxF - maxF_direct = %f" % (maxF -maxF_direct))
|
774
840
|
assert(abs(maxF - maxF_direct) < 1e-6)
|
@@ -1097,8 +1163,8 @@ def state_to_dmvec(psi):
|
|
1097
1163
|
The vectorized density matrix.
|
1098
1164
|
"""
|
1099
1165
|
psi = psi.reshape((psi.size, 1)) # convert to (N,1) shape if necessary
|
1100
|
-
dm =
|
1101
|
-
return dm.
|
1166
|
+
dm = psi @ psi.conj().T
|
1167
|
+
return dm.ravel()
|
1102
1168
|
|
1103
1169
|
|
1104
1170
|
def dmvec_to_state(dmvec, tol=1e-6):
|
@@ -1577,7 +1643,7 @@ def extract_elementary_errorgen_coefficients(errorgen, elementary_errorgen_label
|
|
1577
1643
|
errorgen_basis.create_simple_equivalent('std'))
|
1578
1644
|
else:
|
1579
1645
|
errorgen_std = _bt.change_basis(errorgen, errorgen_basis, "std")
|
1580
|
-
flat_errorgen_std = errorgen_std.toarray().
|
1646
|
+
flat_errorgen_std = errorgen_std.toarray().ravel() if _sps.issparse(errorgen_std) else errorgen_std.ravel()
|
1581
1647
|
|
1582
1648
|
d2 = errorgen_std.shape[0]
|
1583
1649
|
d = int(_np.sqrt(d2))
|
@@ -1593,7 +1659,7 @@ def extract_elementary_errorgen_coefficients(errorgen, elementary_errorgen_label
|
|
1593
1659
|
bel_lbls = key.basis_element_labels
|
1594
1660
|
bmx0 = elementary_errorgen_basis[bel_lbls[0]]
|
1595
1661
|
bmx1 = elementary_errorgen_basis[bel_lbls[1]] if (len(bel_lbls) > 1) else None
|
1596
|
-
flat_projector = _lt.create_elementary_errorgen_dual(key.errorgen_type, bmx0, bmx1, sparse=False).
|
1662
|
+
flat_projector = _lt.create_elementary_errorgen_dual(key.errorgen_type, bmx0, bmx1, sparse=False).ravel()
|
1597
1663
|
projections[key] = _np.real_if_close(_np.vdot(flat_projector, flat_errorgen_std), tol=1000)
|
1598
1664
|
if return_projected_errorgen:
|
1599
1665
|
space_projector[:, i] = flat_projector
|
@@ -1673,7 +1739,7 @@ def project_errorgen(errorgen, elementary_errorgen_type, elementary_errorgen_bas
|
|
1673
1739
|
errorgen_basis.create_simple_equivalent('std'))
|
1674
1740
|
else:
|
1675
1741
|
errorgen_std = _bt.change_basis(errorgen, errorgen_basis, "std")
|
1676
|
-
flat_errorgen_std = errorgen_std.toarray().
|
1742
|
+
flat_errorgen_std = errorgen_std.toarray().ravel() if _sps.issparse(errorgen_std) else errorgen_std.ravel()
|
1677
1743
|
|
1678
1744
|
d2 = errorgen_std.shape[0]
|
1679
1745
|
d = int(_np.sqrt(d2))
|
@@ -1687,7 +1753,7 @@ def project_errorgen(errorgen, elementary_errorgen_type, elementary_errorgen_bas
|
|
1687
1753
|
space_projector = _np.empty((d2 * d2, len(projectors)), complex)
|
1688
1754
|
|
1689
1755
|
for i, (lbl, projector) in enumerate(projectors.items()):
|
1690
|
-
flat_projector = projector.
|
1756
|
+
flat_projector = projector.ravel()
|
1691
1757
|
proj = _np.real_if_close(_np.vdot(flat_projector, flat_errorgen_std), tol=1000)
|
1692
1758
|
if return_projected_errorgen:
|
1693
1759
|
space_projector[:, i] = flat_projector
|
pygsti/tools/pdftools.py
CHANGED
@@ -71,28 +71,3 @@ def classical_fidelity(p, q):
|
|
71
71
|
# sqrt_fidelity += _np.sqrt(x * y)
|
72
72
|
|
73
73
|
return _np.sum([_np.sqrt(x * q.get(event, 0.)) for (event, x) in p.items()]) ** 2
|
74
|
-
|
75
|
-
#return root_fidelity ** 2
|
76
|
-
|
77
|
-
|
78
|
-
# def Hoyer_sparsity_measure(p, n):
|
79
|
-
# """
|
80
|
-
# Computes a measure of the sparsity ("spikyness") of a probability distribution (or a
|
81
|
-
# general real vector).
|
82
|
-
|
83
|
-
# Parameters
|
84
|
-
# ----------
|
85
|
-
# p : dict
|
86
|
-
# The distribution
|
87
|
-
|
88
|
-
# n : the number of possible events (zero probability events do not need to be included in `p`)
|
89
|
-
|
90
|
-
# Returns
|
91
|
-
# -------
|
92
|
-
# float
|
93
|
-
# """
|
94
|
-
# plist = _np.array(list(p.values()))
|
95
|
-
# twonorm = _np.sqrt(_np.sum(plist**2))
|
96
|
-
# onenorm = _np.sum(_np.abs(plist))
|
97
|
-
# max_onenorm_over_twonorm = _np.sqrt(n)
|
98
|
-
# return (max_onenorm_over_twonorm - onenorm/twonorm) / (max_onenorm_over_twonorm - 1)
|