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/layouts/termlayout.py
CHANGED
@@ -57,7 +57,7 @@ class _TermCOPALayoutAtom(_DistributableAtom):
|
|
57
57
|
expanded_circuit_outcomes = _collections.OrderedDict()
|
58
58
|
for i in group:
|
59
59
|
observed_outcomes = None if (dataset is None) else dataset[ds_circuits[i]].outcomes
|
60
|
-
d = unique_complete_circuits[i]
|
60
|
+
d = model.expand_instruments_and_separate_povm(unique_complete_circuits[i], observed_outcomes)
|
61
61
|
expanded_circuit_outcomes_by_unique[i] = d
|
62
62
|
expanded_circuit_outcomes.update(d)
|
63
63
|
|
@@ -71,7 +71,7 @@ class Instrument(_mm.ModelMember, _collections.OrderedDict):
|
|
71
71
|
if state_space is None:
|
72
72
|
state_space = _statespace.default_space_for_dim(member_list[0][1].shape[0])
|
73
73
|
if evotype is None:
|
74
|
-
evotype = _Evotype.cast('default')
|
74
|
+
evotype = _Evotype.cast('default', state_space=state_space)
|
75
75
|
member_list = [(k, v if isinstance(v, _op.LinearOperator) else
|
76
76
|
_op.FullArbitraryOp(v, None, evotype, state_space)) for k, v in member_list]
|
77
77
|
|
@@ -79,10 +79,10 @@ class Instrument(_mm.ModelMember, _collections.OrderedDict):
|
|
79
79
|
"Must specify `state_space` when there are no instrument members!"
|
80
80
|
assert(len(member_list) > 0 or evotype is not None), \
|
81
81
|
"Must specify `evotype` when there are no instrument members!"
|
82
|
-
evotype = _Evotype.cast(evotype) if (evotype is not None) else member_list[0][1].evotype
|
83
82
|
state_space = member_list[0][1].state_space if (state_space is None) \
|
84
83
|
else _statespace.StateSpace.cast(state_space)
|
85
|
-
|
84
|
+
evotype = _Evotype.cast(evotype, state_space=state_space) if (evotype is not None)\
|
85
|
+
else member_list[0][1].evotype
|
86
86
|
items = []
|
87
87
|
for k, member in member_list:
|
88
88
|
assert(evotype == member.evotype), \
|
@@ -77,8 +77,6 @@ class TPInstrument(_mm.ModelMember, _collections.OrderedDict):
|
|
77
77
|
self._readonly = False # until init is done
|
78
78
|
if len(items) > 0:
|
79
79
|
assert(op_matrices is None), "`items` was given when op_matrices != None"
|
80
|
-
|
81
|
-
evotype = _Evotype.cast(evotype)
|
82
80
|
self.param_ops = [] # first element is TP sum (MT), following
|
83
81
|
#elements are fully-param'd (Mi-Mt) for i=0...n-2
|
84
82
|
|
@@ -98,6 +96,7 @@ class TPInstrument(_mm.ModelMember, _collections.OrderedDict):
|
|
98
96
|
"Must specify `state_space` when there are no instrument members!"
|
99
97
|
state_space = _statespace.default_space_for_dim(matrix_list[0][1].shape[0]) if (state_space is None) \
|
100
98
|
else _statespace.StateSpace.cast(state_space)
|
99
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
101
100
|
|
102
101
|
# Create gate objects that are used to parameterize this instrument
|
103
102
|
MT_mx = sum([v for k, v in matrix_list]) # sum-of-instrument-members matrix
|
@@ -125,6 +124,7 @@ class TPInstrument(_mm.ModelMember, _collections.OrderedDict):
|
|
125
124
|
# print(k,":\n",v)
|
126
125
|
else:
|
127
126
|
assert(state_space is not None), "`state_space` cannot be `None` when there are no members!"
|
127
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
128
128
|
|
129
129
|
_collections.OrderedDict.__init__(self, items)
|
130
130
|
_mm.ModelMember.__init__(self, state_space, evotype)
|
@@ -340,23 +340,6 @@ class ModelMember(ModelChild, _NicelySerializable):
|
|
340
340
|
if (self.parent is not None) and (force or self.parent._obj_refcount(self) == 0):
|
341
341
|
self._parent = None
|
342
342
|
|
343
|
-
# UNUSED - as this doesn't mark parameter for reallocation like it used to
|
344
|
-
#def clear_gpindices(self):
|
345
|
-
# """
|
346
|
-
# Sets gpindices to None, along with any submembers' gpindices.
|
347
|
-
#
|
348
|
-
# This essentially marks these members for parameter re-allocation
|
349
|
-
# (e.g. if the number - not just the value - of parameters they have
|
350
|
-
# changes).
|
351
|
-
#
|
352
|
-
# Returns
|
353
|
-
# -------
|
354
|
-
# None
|
355
|
-
# """
|
356
|
-
# for subm in self.submembers():
|
357
|
-
# subm.clear_gpindices()
|
358
|
-
# self._gpindices = None
|
359
|
-
|
360
343
|
def set_gpindices(self, gpindices, parent, memo=None):
|
361
344
|
"""
|
362
345
|
Set the parent and indices into the parent's parameter vector that are used by this ModelMember object.
|
@@ -38,6 +38,7 @@ from .staticstdop import StaticStandardOp
|
|
38
38
|
from .staticunitaryop import StaticUnitaryOp
|
39
39
|
from .stochasticop import StochasticNoiseOp
|
40
40
|
from .lindbladcoefficients import LindbladCoefficientBlock as _LindbladCoefficientBlock
|
41
|
+
from .affineshiftop import AffineShiftOp
|
41
42
|
from pygsti.baseobjs import statespace as _statespace
|
42
43
|
from pygsti.tools import basistools as _bt
|
43
44
|
from pygsti.tools import optools as _ot
|
@@ -474,18 +475,16 @@ def optimize_operation(op_to_optimize, target_op):
|
|
474
475
|
return
|
475
476
|
|
476
477
|
from pygsti import optimize as _opt
|
477
|
-
from pygsti.tools import matrixtools as _mt
|
478
478
|
assert(target_op.dim == op_to_optimize.dim) # operations must have the same overall dimension
|
479
479
|
targetMatrix = target_op.to_dense() if isinstance(target_op, LinearOperator) else target_op
|
480
480
|
|
481
481
|
def _objective_func(param_vec):
|
482
482
|
op_to_optimize.from_vector(param_vec)
|
483
|
-
return
|
483
|
+
return _np.linalg.norm(op_to_optimize.to_dense() - targetMatrix)
|
484
484
|
|
485
485
|
x0 = op_to_optimize.to_vector()
|
486
486
|
minSol = _opt.minimize(_objective_func, x0, method='BFGS', maxiter=10000, maxfev=10000,
|
487
487
|
tol=1e-6, callback=None)
|
488
488
|
|
489
489
|
op_to_optimize.from_vector(minSol.x)
|
490
|
-
|
491
|
-
# _mt.frobeniusnorm(op_to_optimize-targetMatrix))
|
490
|
+
return
|
@@ -0,0 +1,206 @@
|
|
1
|
+
"""
|
2
|
+
The AffineShiftOp class and supporting functionality.
|
3
|
+
"""
|
4
|
+
#***************************************************************************************************
|
5
|
+
# Copyright 2015, 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
6
|
+
# Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government retains certain rights
|
7
|
+
# in this software.
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
9
|
+
# in compliance with the License. You may obtain a copy of the License at
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0 or in the LICENSE file in the root pyGSTi directory.
|
11
|
+
#***************************************************************************************************
|
12
|
+
|
13
|
+
import numpy as _np
|
14
|
+
|
15
|
+
from pygsti.modelmembers.operations.denseop import DenseOperator as _DenseOperator
|
16
|
+
from pygsti.modelmembers.operations.linearop import LinearOperator as _LinearOperator
|
17
|
+
from pygsti.baseobjs.protectedarray import ProtectedArray as _ProtectedArray
|
18
|
+
|
19
|
+
|
20
|
+
class AffineShiftOp(_DenseOperator):
|
21
|
+
"""
|
22
|
+
An operation matrix that induces an affine shift.
|
23
|
+
|
24
|
+
An operation matrix with ones on the diagonal and nonzero values in
|
25
|
+
the first columns.
|
26
|
+
|
27
|
+
Meant to work in the Pauli basis for now.
|
28
|
+
|
29
|
+
Parameters
|
30
|
+
----------
|
31
|
+
m : array_like or LinearOperator
|
32
|
+
a square 2D array-like or LinearOperator object representing the operation action.
|
33
|
+
The shape of m sets the dimension of the operation.
|
34
|
+
|
35
|
+
basis : Basis or {'pp','gm','std'} or None
|
36
|
+
The basis used to construct the Hilbert-Schmidt space representation
|
37
|
+
of this state as a super-operator. If None, certain functionality,
|
38
|
+
such as access to Kraus operators, will be unavailable.
|
39
|
+
|
40
|
+
evotype : Evotype or str, optional
|
41
|
+
The evolution type. The special value `"default"` is equivalent
|
42
|
+
to specifying the value of `pygsti.evotypes.Evotype.default_evotype`.
|
43
|
+
|
44
|
+
state_space : StateSpace, optional
|
45
|
+
The state space for this operation. If `None` a default state space
|
46
|
+
with the appropriate number of qubits is used.
|
47
|
+
|
48
|
+
Attributes
|
49
|
+
----------
|
50
|
+
base : numpy.ndarray
|
51
|
+
Direct access to the underlying process matrix data.
|
52
|
+
"""
|
53
|
+
|
54
|
+
def __init__(self, m, basis=None, evotype="default", state_space=None):
|
55
|
+
#LinearOperator.__init__(self, LinearOperator.convert_to_matrix(m))
|
56
|
+
mx = _LinearOperator.convert_to_matrix(m)
|
57
|
+
assert(_np.isrealobj(mx)), "FullTPOp must have *real* values!"
|
58
|
+
|
59
|
+
#this line checks whether the input matrix has the correct
|
60
|
+
#arrowhead structure.
|
61
|
+
if not (_np.allclose(_np.diag(mx), 1) and _np.allclose((mx-_np.eye(mx.shape[0]))[:, 1:], 0.0)):
|
62
|
+
raise ValueError("Cannot create AffineShiftOp: "
|
63
|
+
"Matrix does not have the correct arrowhead structure")
|
64
|
+
_DenseOperator.__init__(self, mx, basis, evotype, state_space)
|
65
|
+
assert(self._rep.base.flags['C_CONTIGUOUS'] and self._rep.base.flags['OWNDATA'])
|
66
|
+
assert(isinstance(self._ptr, _ProtectedArray))
|
67
|
+
|
68
|
+
self._paramlbls = _np.array(["MxElement %d,0" % (i) for i in range(1, self.dim)],
|
69
|
+
dtype=object)
|
70
|
+
|
71
|
+
@property
|
72
|
+
def _ptr(self):
|
73
|
+
"""
|
74
|
+
The underlying dense process matrix.
|
75
|
+
"""
|
76
|
+
return _ProtectedArray(self._rep.base, indices_to_protect=[(0,slice(None,None,None)),
|
77
|
+
(slice(1,None, None), slice(1, None, None))])
|
78
|
+
|
79
|
+
def set_dense(self, m):
|
80
|
+
"""
|
81
|
+
Set the dense-matrix value of this operation.
|
82
|
+
|
83
|
+
Attempts to modify operation parameters so that the specified raw
|
84
|
+
operation matrix becomes m. Will raise ValueError if this operation
|
85
|
+
is not possible.
|
86
|
+
|
87
|
+
Parameters
|
88
|
+
----------
|
89
|
+
m : array_like or LinearOperator
|
90
|
+
An array of shape (dim, dim) or LinearOperator representing the operation action.
|
91
|
+
|
92
|
+
Returns
|
93
|
+
-------
|
94
|
+
None
|
95
|
+
"""
|
96
|
+
mx = _LinearOperator.convert_to_matrix(m)
|
97
|
+
if(mx.shape != (self.dim, self.dim)):
|
98
|
+
raise ValueError("Argument must be a (%d,%d) matrix!"
|
99
|
+
% (self.dim, self.dim))
|
100
|
+
if not (_np.allclose(_np.diag(mx), 1) and _np.allclose((mx-_np.eye(mx.shape[0]))[:, 1:], 0.0)):
|
101
|
+
raise ValueError("Cannot create AffineShiftOp: "
|
102
|
+
"Matrix does not have the correct arrowhead structure")
|
103
|
+
#For further debugging: + "\n".join([str(e) for e in mx[0,:]])
|
104
|
+
self._ptr[1:, 0] = mx[1:, 0]
|
105
|
+
self._ptr_has_changed()
|
106
|
+
self.dirty = True
|
107
|
+
|
108
|
+
@property
|
109
|
+
def num_params(self):
|
110
|
+
"""
|
111
|
+
Get the number of independent parameters which specify this operation.
|
112
|
+
|
113
|
+
Returns
|
114
|
+
-------
|
115
|
+
int
|
116
|
+
the number of independent parameters.
|
117
|
+
"""
|
118
|
+
return self.dim-1
|
119
|
+
|
120
|
+
def to_vector(self):
|
121
|
+
"""
|
122
|
+
Get the operation parameters as an array of values.
|
123
|
+
|
124
|
+
Returns
|
125
|
+
-------
|
126
|
+
numpy array
|
127
|
+
The operation parameters as a 1D array with length num_params().
|
128
|
+
"""
|
129
|
+
# Use flatten (rather than ravel) to ensure a copy is made.
|
130
|
+
return self._ptr[1:,0].flatten() # .real in case of complex matrices?
|
131
|
+
|
132
|
+
def from_vector(self, v, close=False, dirty_value=True):
|
133
|
+
"""
|
134
|
+
Initialize the operation using a vector of parameters.
|
135
|
+
|
136
|
+
Parameters
|
137
|
+
----------
|
138
|
+
v : numpy array
|
139
|
+
The 1D vector of operation parameters. Length
|
140
|
+
must == num_params()
|
141
|
+
|
142
|
+
close : bool, optional
|
143
|
+
Whether `v` is close to this operation's current
|
144
|
+
set of parameters. Under some circumstances, when this
|
145
|
+
is true this call can be completed more quickly.
|
146
|
+
|
147
|
+
dirty_value : bool, optional
|
148
|
+
The value to set this object's "dirty flag" to before exiting this
|
149
|
+
call. This is passed as an argument so it can be updated *recursively*.
|
150
|
+
Leave this set to `True` unless you know what you're doing.
|
151
|
+
|
152
|
+
Returns
|
153
|
+
-------
|
154
|
+
None
|
155
|
+
"""
|
156
|
+
#TODO: Circle back to comments about it being faster to directly
|
157
|
+
#operate on the rep.
|
158
|
+
#assert(self._ptr.shape == (self.dim, self.dim))
|
159
|
+
assert (len(v) == self.dim-1)
|
160
|
+
self._ptr[1:, 0] = v
|
161
|
+
#self._rep.base[1:, :] = v.reshape((self.dim - 1, self.dim)) # faster than line above
|
162
|
+
#self._rep.base.flat[self.dim:] = v # faster still
|
163
|
+
self._ptr_has_changed() # because _rep.base == _ptr (same memory)
|
164
|
+
self.dirty = dirty_value
|
165
|
+
|
166
|
+
def deriv_wrt_params(self, wrt_filter=None):
|
167
|
+
"""
|
168
|
+
The element-wise derivative this operation.
|
169
|
+
|
170
|
+
Construct a matrix whose columns are the vectorized
|
171
|
+
derivatives of the flattened operation matrix with respect to a
|
172
|
+
single operation parameter. Thus, each column is of length
|
173
|
+
op_dim^2 and there is one column per operation parameter.
|
174
|
+
|
175
|
+
Parameters
|
176
|
+
----------
|
177
|
+
wrt_filter : list or numpy.ndarray
|
178
|
+
List of parameter indices to take derivative with respect to.
|
179
|
+
(None means to use all the this operation's parameters.)
|
180
|
+
|
181
|
+
Returns
|
182
|
+
-------
|
183
|
+
numpy array
|
184
|
+
Array of derivatives with shape (dimension^2, num_params)
|
185
|
+
"""
|
186
|
+
derivMx = _np.identity(self.dim**2, 'd') # TP operations are assumed to be real
|
187
|
+
|
188
|
+
derivMx = derivMx[:, self.dim::self.dim] # Extract only columns of derivMx matrix
|
189
|
+
#corresponding to the first column of the PTR less the first row.
|
190
|
+
|
191
|
+
if wrt_filter is None:
|
192
|
+
return derivMx
|
193
|
+
else:
|
194
|
+
return _np.take(derivMx, wrt_filter, axis=1)
|
195
|
+
|
196
|
+
def has_nonzero_hessian(self):
|
197
|
+
"""
|
198
|
+
Whether this operation has a non-zero Hessian with respect to its parameters.
|
199
|
+
|
200
|
+
(i.e. whether it only depends linearly on its parameters or not)
|
201
|
+
|
202
|
+
Returns
|
203
|
+
-------
|
204
|
+
bool
|
205
|
+
"""
|
206
|
+
return False
|
@@ -63,7 +63,7 @@ class ComposedErrorgen(_LinearOperator):
|
|
63
63
|
|
64
64
|
if evotype == "auto":
|
65
65
|
evotype = errgens_to_compose[0]._evotype
|
66
|
-
evotype = _Evotype.cast(evotype)
|
66
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
67
67
|
assert(all([evotype == eg._evotype for eg in errgens_to_compose])), \
|
68
68
|
"All error generators must have the same evolution type (%s expected)!" % evotype
|
69
69
|
|
@@ -69,7 +69,7 @@ class ComposedOp(_LinearOperator):
|
|
69
69
|
evotype = ops_to_compose[0]._evotype
|
70
70
|
assert(all([evotype == operation._evotype for operation in ops_to_compose])), \
|
71
71
|
"All operations must have the same evolution type (%s expected)!" % evotype
|
72
|
-
evotype = _Evotype.cast(evotype)
|
72
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
73
73
|
|
74
74
|
rep = self._create_rep_object(evotype, state_space)
|
75
75
|
|
@@ -491,10 +491,6 @@ class ComposedOp(_LinearOperator):
|
|
491
491
|
|
492
492
|
self.terms[order] = terms
|
493
493
|
|
494
|
-
#def _decompose_indices(x):
|
495
|
-
# return tuple(_modelmember._decompose_gpindices(
|
496
|
-
# self.gpindices, _np.array(x, _np.int64)))
|
497
|
-
|
498
494
|
mapvec = _np.ascontiguousarray(_np.zeros(max_polynomial_vars, _np.int64))
|
499
495
|
for ii, i in enumerate(gpindices_array):
|
500
496
|
mapvec[i] = ii
|
@@ -555,25 +551,6 @@ class ComposedOp(_LinearOperator):
|
|
555
551
|
if mag >= min_term_mag:
|
556
552
|
terms.append(_term.compose_terms_with_mag(factors, mag))
|
557
553
|
return terms
|
558
|
-
#def _decompose_indices(x):
|
559
|
-
# return tuple(_modelmember._decompose_gpindices(
|
560
|
-
# self.gpindices, _np.array(x, _np.int64)))
|
561
|
-
#
|
562
|
-
#mapvec = _np.ascontiguousarray(_np.zeros(max_polynomial_vars,_np.int64))
|
563
|
-
#for ii,i in enumerate(self.gpindices_as_array()):
|
564
|
-
# mapvec[i] = ii
|
565
|
-
#
|
566
|
-
##poly_coeffs = [t.coeff.map_indices(_decompose_indices) for t in terms] # with *local* indices
|
567
|
-
#poly_coeffs = [t.coeff.mapvec_indices(mapvec) for t in terms] # with *local* indices
|
568
|
-
#tapes = [poly.compact(complex_coeff_tape=True) for poly in poly_coeffs]
|
569
|
-
#if len(tapes) > 0:
|
570
|
-
# vtape = _np.concatenate([t[0] for t in tapes])
|
571
|
-
# ctape = _np.concatenate([t[1] for t in tapes])
|
572
|
-
#else:
|
573
|
-
# vtape = _np.empty(0, _np.int64)
|
574
|
-
# ctape = _np.empty(0, complex)
|
575
|
-
#coeffs_as_compact_polys = (vtape, ctape)
|
576
|
-
#self.local_term_poly_coeffs[order] = coeffs_as_compact_polys
|
577
554
|
|
578
555
|
@property
|
579
556
|
def total_term_magnitude(self):
|
@@ -313,7 +313,7 @@ class DenseOperator(DenseOperatorInterface, _KrausOperatorInterface, _LinearOper
|
|
313
313
|
mx = _LinearOperator.convert_to_matrix(mx)
|
314
314
|
state_space = _statespace.default_space_for_dim(mx.shape[0]) if (state_space is None) \
|
315
315
|
else _statespace.StateSpace.cast(state_space)
|
316
|
-
evotype = _Evotype.cast(evotype)
|
316
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
317
317
|
self._basis = _Basis.cast(basis, state_space.dim) if (basis is not None) else None # for Hilbert-Schmidt space
|
318
318
|
rep = evotype.create_dense_superop_rep(mx, self._basis, state_space)
|
319
319
|
_LinearOperator.__init__(self, rep, evotype)
|
@@ -416,11 +416,11 @@ class DenseOperator(DenseOperatorInterface, _KrausOperatorInterface, _LinearOper
|
|
416
416
|
#CHECK 1 (to unit test?) REMOVE
|
417
417
|
#tmp_std = _bt.change_basis(superop_mx, self._basis, 'std')
|
418
418
|
#B = _bt.basis_matrices('std', superop_mx.shape[0])
|
419
|
-
#check_superop = sum([ choi_mx[i,j] * _np.kron(B[i], B[j].
|
419
|
+
#check_superop = sum([ choi_mx[i,j] * _np.kron(B[i], B[j].conjugate()) for i in range(d*d) for j in range(d*d)])
|
420
420
|
#assert(_np.allclose(check_superop, tmp_std))
|
421
421
|
|
422
|
-
evals, evecs = _np.linalg.
|
423
|
-
|
422
|
+
evals, evecs = _np.linalg.eigh(choi_mx)
|
423
|
+
assert(_np.allclose(evecs @ _np.diag(evals) @ (evecs.conjugate().T), choi_mx))
|
424
424
|
TOL = 1e-7 # consider lowering this tolerance as it leads to errors of this order in the Kraus decomp
|
425
425
|
if any([ev <= -TOL for ev in evals]):
|
426
426
|
raise ValueError("Cannot compute Kraus decomposition of non-positive-definite superoperator!")
|
@@ -533,7 +533,7 @@ class DenseUnitaryOperator(DenseOperatorInterface, _KrausOperatorInterface, _Lin
|
|
533
533
|
state_space = _statespace.default_space_for_udim(mx.shape[0]) if (state_space is None) \
|
534
534
|
else _statespace.StateSpace.cast(state_space)
|
535
535
|
basis = _Basis.cast(basis, state_space.dim) # basis for Hilbert-Schmidt (superop) space
|
536
|
-
evotype = _Evotype.cast(evotype)
|
536
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
537
537
|
|
538
538
|
#Try to create a dense unitary rep. If this fails, see if a dense superop rep
|
539
539
|
# can be created, as this type of rep can also hold arbitrary unitary ops.
|
@@ -432,13 +432,13 @@ class EigenvalueParamDenseOp(_DenseOperator):
|
|
432
432
|
dMx = _np.zeros((self.dim, self.dim), 'complex')
|
433
433
|
for prefactor, (i, j) in pdesc:
|
434
434
|
dMx[i, j] = prefactor
|
435
|
-
tmp =
|
435
|
+
tmp = self.B @ (dMx @ self.Bi)
|
436
436
|
if _np.linalg.norm(tmp.imag) >= IMAG_TOL: # just a warning until we figure this out.
|
437
437
|
print("EigenvalueParamDenseOp deriv_wrt_params WARNING:"
|
438
438
|
" Imag part = ", _np.linalg.norm(tmp.imag), " pdesc = ", pdesc) # pragma: no cover
|
439
439
|
#assert(_np.linalg.norm(tmp.imag) < IMAG_TOL), \
|
440
440
|
# "Imaginary mag = %g!" % _np.linalg.norm(tmp.imag)
|
441
|
-
derivMx[:, k] = tmp.real.
|
441
|
+
derivMx[:, k] = tmp.real.ravel()
|
442
442
|
|
443
443
|
if wrt_filter is None:
|
444
444
|
return derivMx
|
@@ -11,10 +11,10 @@ The EmbeddedErrorgen class and supporting functionality.
|
|
11
11
|
#***************************************************************************************************
|
12
12
|
|
13
13
|
import collections as _collections
|
14
|
+
from pygsti.baseobjs.basis import Basis as _Basis
|
14
15
|
import warnings as _warnings
|
15
16
|
|
16
17
|
from pygsti.modelmembers.operations.embeddedop import EmbeddedOp as _EmbeddedOp
|
17
|
-
from pygsti.baseobjs.basis import Basis as _Basis, EmbeddedBasis as _EmbeddedBasis
|
18
18
|
|
19
19
|
|
20
20
|
# Idea:
|
@@ -18,7 +18,6 @@ import scipy.sparse as _sps
|
|
18
18
|
|
19
19
|
from pygsti.modelmembers.operations.linearop import LinearOperator as _LinearOperator
|
20
20
|
from pygsti.modelmembers import modelmember as _modelmember
|
21
|
-
from pygsti.baseobjs.basis import EmbeddedBasis as _EmbeddedBasis
|
22
21
|
from pygsti.baseobjs.statespace import StateSpace as _StateSpace
|
23
22
|
|
24
23
|
|
@@ -699,10 +699,13 @@ class ExpErrorgenOp(_LinearOperator, _ErrorGeneratorContainer):
|
|
699
699
|
|
700
700
|
#just act on postfactor and Lindbladian exponent:
|
701
701
|
if typ == "prep":
|
702
|
-
mx =
|
702
|
+
mx = Uinv @ mx
|
703
703
|
else:
|
704
|
-
mx =
|
704
|
+
mx = mx @ U
|
705
705
|
self.set_dense(mx) # calls _update_rep() and sets dirty flag
|
706
|
+
else:
|
707
|
+
raise ValueError("Invalid transform for this LindbladErrorgen: type %s"
|
708
|
+
% str(type(s)))
|
706
709
|
|
707
710
|
def __str__(self):
|
708
711
|
s = "Exponentiated operation map with dim = %d, num params = %d\n" % \
|
@@ -93,6 +93,7 @@ class FullArbitraryOp(_DenseOperator):
|
|
93
93
|
numpy array
|
94
94
|
The operation parameters as a 1D array with length num_params().
|
95
95
|
"""
|
96
|
+
# Use flatten (rather than ravel) to ensure a copy is made.
|
96
97
|
return self._ptr.flatten()
|
97
98
|
|
98
99
|
def from_vector(self, v, close=False, dirty_value=True):
|
@@ -42,7 +42,7 @@ class FullCPTPOp(_KrausOperatorInterface, _LinearOperator):
|
|
42
42
|
choi_mx = _LinearOperator.convert_to_matrix(choi_mx)
|
43
43
|
state_space = _statespace.default_space_for_dim(choi_mx.shape[0]) if (state_space is None) \
|
44
44
|
else _statespace.StateSpace.cast(state_space)
|
45
|
-
evotype = _Evotype.cast(evotype)
|
45
|
+
evotype = _Evotype.cast(evotype, state_space=state_space)
|
46
46
|
self._basis = _Basis.cast(basis, state_space.dim) if (basis is not None) else None # for Hilbert-Schmidt space
|
47
47
|
|
48
48
|
#scratch space
|
@@ -93,7 +93,7 @@ class FullCPTPOp(_KrausOperatorInterface, _LinearOperator):
|
|
93
93
|
Lmx = _np.linalg.cholesky(choi_mx)
|
94
94
|
|
95
95
|
#check TP condition: that diagonal els of Lmx squared add to 1.0
|
96
|
-
Lmx_norm = _np.
|
96
|
+
Lmx_norm = _np.linalg.norm(Lmx) # = sqrt(tr(Lmx' Lmx))
|
97
97
|
assert(_np.isclose(Lmx_norm, 1.0)), "Cholesky decomp didn't preserve trace=1!"
|
98
98
|
|
99
99
|
self.params = _np.empty(dim**2, 'd')
|
@@ -10,14 +10,25 @@ The FullTPOp class and supporting functionality.
|
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0 or in the LICENSE file in the root pyGSTi directory.
|
11
11
|
#***************************************************************************************************
|
12
12
|
|
13
|
-
|
13
|
+
from __future__ import annotations
|
14
|
+
from typing import Tuple, TYPE_CHECKING
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
import torch as _torch
|
17
|
+
try:
|
18
|
+
import torch as _torch
|
19
|
+
except ImportError:
|
20
|
+
pass
|
14
21
|
|
22
|
+
import numpy as _np
|
15
23
|
from pygsti.modelmembers.operations.denseop import DenseOperator as _DenseOperator
|
16
24
|
from pygsti.modelmembers.operations.linearop import LinearOperator as _LinearOperator
|
17
25
|
from pygsti.baseobjs.protectedarray import ProtectedArray as _ProtectedArray
|
26
|
+
from pygsti.modelmembers.torchable import Torchable as _Torchable
|
27
|
+
|
28
|
+
|
18
29
|
|
19
30
|
|
20
|
-
class FullTPOp(_DenseOperator):
|
31
|
+
class FullTPOp(_DenseOperator, _Torchable):
|
21
32
|
"""
|
22
33
|
A trace-preserving operation matrix.
|
23
34
|
|
@@ -52,11 +63,9 @@ class FullTPOp(_DenseOperator):
|
|
52
63
|
"""
|
53
64
|
|
54
65
|
def __init__(self, m, basis=None, evotype="default", state_space=None):
|
55
|
-
#LinearOperator.__init__(self, LinearOperator.convert_to_matrix(m))
|
56
66
|
mx = _LinearOperator.convert_to_matrix(m)
|
57
67
|
assert(_np.isrealobj(mx)), "FullTPOp must have *real* values!"
|
58
|
-
if not (_np.isclose(mx[0, 0], 1.0)
|
59
|
-
and _np.allclose(mx[0, 1:], 0.0)):
|
68
|
+
if not (_np.isclose(mx[0, 0], 1.0) and _np.allclose(mx[0, 1:], 0.0)):
|
60
69
|
raise ValueError("Cannot create FullTPOp: "
|
61
70
|
"invalid form for 1st row!")
|
62
71
|
_DenseOperator.__init__(self, mx, basis, evotype, state_space)
|
@@ -122,7 +131,7 @@ class FullTPOp(_DenseOperator):
|
|
122
131
|
numpy array
|
123
132
|
The operation parameters as a 1D array with length num_params().
|
124
133
|
"""
|
125
|
-
return self._ptr.
|
134
|
+
return self._ptr.ravel()[self.dim:].copy() # .real in case of complex matrices?
|
126
135
|
|
127
136
|
def from_vector(self, v, close=False, dirty_value=True):
|
128
137
|
"""
|
@@ -155,6 +164,19 @@ class FullTPOp(_DenseOperator):
|
|
155
164
|
self._ptr_has_changed() # because _rep.base == _ptr (same memory)
|
156
165
|
self.dirty = dirty_value
|
157
166
|
|
167
|
+
def stateless_data(self) -> Tuple[int]:
|
168
|
+
return (self.dim,)
|
169
|
+
|
170
|
+
@staticmethod
|
171
|
+
def torch_base(sd: Tuple[int], t_param: _torch.Tensor) -> _torch.Tensor:
|
172
|
+
dim = sd[0]
|
173
|
+
t_const = _torch.zeros(size=(1, dim), dtype=_torch.double)
|
174
|
+
t_const[0,0] = 1.0
|
175
|
+
t_param_mat = t_param.reshape((dim - 1, dim))
|
176
|
+
t = _torch.row_stack((t_const, t_param_mat))
|
177
|
+
return t
|
178
|
+
|
179
|
+
|
158
180
|
def deriv_wrt_params(self, wrt_filter=None):
|
159
181
|
"""
|
160
182
|
The element-wise derivative this operation.
|
@@ -98,7 +98,8 @@ class FullUnitaryOp(_DenseUnitaryOperator):
|
|
98
98
|
numpy array
|
99
99
|
The operation parameters as a 1D array with length num_params().
|
100
100
|
"""
|
101
|
-
|
101
|
+
# _np.concatenate will make a copy for us, so use ravel instead of flatten.
|
102
|
+
return _np.concatenate((self._ptr.real.ravel(), self._ptr.imag.ravel()), axis=0)
|
102
103
|
|
103
104
|
def from_vector(self, v, close=False, dirty_value=True):
|
104
105
|
"""
|
@@ -200,7 +201,7 @@ class FullUnitaryOp(_DenseUnitaryOperator):
|
|
200
201
|
Uinv = s.transform_matrix_inverse
|
201
202
|
|
202
203
|
my_superop_mx = _ot.unitary_to_superop(self._ptr, self._basis)
|
203
|
-
my_superop_mx =
|
204
|
+
my_superop_mx = Uinv @ (my_superop_mx @ U)
|
204
205
|
|
205
206
|
self._ptr[:, :] = _ot.superop_to_unitary(my_superop_mx, self._basis)
|
206
207
|
self._ptr_has_changed()
|
@@ -250,9 +251,9 @@ class FullUnitaryOp(_DenseUnitaryOperator):
|
|
250
251
|
|
251
252
|
#Note: this code may need to be tweaked to work with sparse matrices
|
252
253
|
if typ == "prep":
|
253
|
-
my_superop_mx =
|
254
|
+
my_superop_mx = Uinv @ my_superop_mx
|
254
255
|
else:
|
255
|
-
my_superop_mx =
|
256
|
+
my_superop_mx = my_superop_mx @ U
|
256
257
|
|
257
258
|
self._ptr[:, :] = _ot.superop_to_unitary(my_superop_mx, self._basis)
|
258
259
|
self._ptr_has_changed()
|