def __init__(self, vec, basis, truncate=False, evotype="default", state_space=None): vector = _State._to_vector(vec) basis = _Basis.cast(basis, len(vector)) self.basis = basis self.basis_mxs = basis.elements # shape (len(vec), dmDim, dmDim) self.basis_mxs = _np.rollaxis(self.basis_mxs, 0, 3) # shape (dmDim, dmDim, len(vec)) assert(self.basis_mxs.shape[-1] == len(vector)) # set self.params and self.dmDim self._set_params_from_vector(vector, truncate) #parameter labels (parameter encode the Cholesky Lmx) labels = [] for i, ilbl in enumerate(basis.labels[1:]): for j, jlbl in enumerate(basis.labels[1:]): if i == j: labels.append("%s diagonal element of density matrix Cholesky decomp" % ilbl) elif j < i: labels.append("Re[(%s,%s) element of density matrix Cholesky decomp]" % (ilbl, jlbl)) else: labels.append("Im[(%s,%s) element of density matrix Cholesky decomp]" % (ilbl, jlbl)) #scratch space self.Lmx = _np.zeros((self.dmDim, self.dmDim), 'complex') state_space = _statespace.default_space_for_dim(len(vector)) if (state_space is None) \ else _statespace.StateSpace.cast(state_space) evotype = _Evotype.cast(evotype) _DenseState.__init__(self, vector, evotype, state_space) self._paramlbls = _np.array(labels, dtype=object)
def build_gate(): dim = 4 evotype = Evotype.cast('default') state_space = statespace.default_space_for_dim(dim) rep = evotype.create_dense_superop_rep(np.identity(dim, 'd'), state_space) return op.LinearOperator(rep, evotype)
def create_from_dmvec(superket_vector, state_type, basis='pp', evotype='default', state_space=None): state_type_preferences = (state_type, ) if isinstance(state_type, str) else state_type if state_space is None: state_space = _statespace.default_space_for_dim(len(superket_vector)) for typ in state_type_preferences: try: if typ == "static": st = StaticState(superket_vector, evotype, state_space) elif typ == "full": st = FullState(superket_vector, evotype, state_space) elif typ == "full TP": st = TPState(superket_vector, basis, evotype, state_space) elif typ == "TrueCPTP": # a non-lindbladian CPTP state that hasn't worked well... truncate = False st = CPTPState(superket_vector, basis, truncate, evotype, state_space) elif _ot.is_valid_lindblad_paramtype(typ): from ..operations import LindbladErrorgen as _LindbladErrorgen, ExpErrorgenOp as _ExpErrorgenOp try: dmvec = _bt.change_basis(superket_vector, basis, 'std') purevec = _ot.dmvec_to_state( dmvec ) # raises error if dmvec does not correspond to a pure state static_state = StaticPureState(purevec, basis, evotype, state_space) except ValueError: static_state = StaticState(superket_vector, evotype, state_space) proj_basis = 'PP' if state_space.is_entirely_qubits else basis errorgen = _LindbladErrorgen.from_error_generator( state_space.dim, typ, proj_basis, basis, truncate=True, evotype=evotype) return ComposedState(static_state, _ExpErrorgenOp(errorgen)) else: # Anything else we try to convert to a pure vector and convert the pure state vector dmvec = _bt.change_basis(superket_vector, basis, 'std') purevec = _ot.dmvec_to_state(dmvec) st = create_from_pure_vector(purevec, typ, basis, evotype, state_space) return st except (ValueError, AssertionError): pass # move on to next type raise ValueError( "Could not create a state of type(s) %s from the given superket vector!" % (str(state_type)))
def __init__(self, vec, evotype, state_space): vec = _State._to_vector(vec) state_space = _statespace.default_space_for_dim(vec.shape[0]) if (state_space is None) \ else _statespace.StateSpace.cast(state_space) evotype = _Evotype.cast(evotype) rep = evotype.create_dense_state_rep(vec, state_space) _State.__init__(self, rep, evotype) DenseStateInterface.__init__(self)
def __init__(self, mx, evotype, state_space=None): """ Initialize a new LinearOperator """ mx = _LinearOperator.convert_to_matrix(mx) state_space = _statespace.default_space_for_dim(mx.shape[0]) if (state_space is None) \ else _statespace.StateSpace.cast(state_space) evotype = _Evotype.cast(evotype) rep = evotype.create_dense_superop_rep(mx, state_space) _LinearOperator.__init__(self, rep, evotype) DenseOperatorInterface.__init__(self)
def test_instance(self): state_space = statespace.default_space_for_dim(4) sop = op.StochasticNoiseOp(state_space) sop.from_vector(np.array([0.1, 0.0, 0.0])) self.assertArraysAlmostEqual(sop.to_vector(), np.array([0.1, 0., 0.])) expected_mx = np.identity(4) expected_mx[2, 2] = expected_mx[3, 3] = 0.98 # = 2*(0.1^2) self.assertArraysAlmostEqual(sop.to_dense(), expected_mx) rho = create_spam_vector("0", "Q0", Basis.cast("pp", [4])) self.assertAlmostEqual( float(np.dot(rho.T, np.dot(sop.to_dense(), rho))), 0.99) # b/c X dephasing w/rate is 0.1^2 = 0.01
def test_base_state(self): state_space = statespace.default_space_for_dim(4) evotype = Evotype.cast('default') rep = evotype.create_dense_state_rep(np.zeros(4, 'd'), state_space) raw = states.State(rep, evotype) T = FullGaugeGroupElement( np.array([[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], 'd')) with self.assertRaises(NotImplementedError): raw.to_dense() with self.assertRaises(NotImplementedError): raw.transform_inplace(T) with self.assertRaises(NotImplementedError): raw.depolarize(0.01)
def test_depol_noise_op(self): state_space = statespace.default_space_for_dim(4) dop = op.DepolarizeOp(state_space) dop.from_vector(np.array([0.1])) self.assertArraysAlmostEqual(dop.to_vector(), np.array([0.1])) expected_mx = np.identity(4) expected_mx[1, 1] = expected_mx[2, 2] = expected_mx[3, 3] = 0.96 # = 4*(0.1^2) self.assertArraysAlmostEqual(dop.to_dense(), expected_mx) rho = create_spam_vector("0", "Q0", Basis.cast("pp", [4])) # b/c both X and Y dephasing rates => 0.01 reduction self.assertAlmostEqual( float(np.dot(rho.T, np.dot(dop.to_dense(), rho))), 0.98)
def create_effect_from_dmvec(superket_vector, effect_type, basis='pp', evotype='default', state_space=None, on_construction_error='warn'): effect_type_preferences = (effect_type,) if isinstance(effect_type, str) else effect_type if state_space is None: state_space = _statespace.default_space_for_dim(len(superket_vector)) for typ in effect_type_preferences: try: if typ == "static": ef = StaticPOVMEffect(superket_vector, evotype, state_space) elif typ == "full": ef = FullPOVMEffect(superket_vector, evotype, state_space) elif _ot.is_valid_lindblad_paramtype(typ): from ..operations import LindbladErrorgen as _LindbladErrorgen, ExpErrorgenOp as _ExpErrorgenOp try: dmvec = _bt.change_basis(superket_vector, basis, 'std') purevec = _ot.dmvec_to_state(dmvec) # raises error if dmvec does not correspond to a pure state static_effect = StaticPOVMPureEffect(purevec, basis, evotype, state_space) except ValueError: static_effect = StaticPOVMEffect(superket_vector, evotype, state_space) proj_basis = 'PP' if state_space.is_entirely_qubits else basis errorgen = _LindbladErrorgen.from_error_generator(state_space.dim, typ, proj_basis, basis, truncate=True, evotype=evotype) ef = ComposedPOVMEffect(static_effect, _ExpErrorgenOp(errorgen)) else: # Anything else we try to convert to a pure vector and convert the pure state vector dmvec = _bt.change_basis(superket_vector, basis, 'std') purevec = _ot.dmvec_to_state(dmvec) # raises error if dmvec does not correspond to a pure state ef = create_effect_from_pure_vector(purevec, typ, basis, evotype, state_space) return ef except (ValueError, AssertionError) as err: if on_construction_error == 'raise': raise err elif on_construction_error == 'warn': print('Failed to construct effect with type "{}" with error: {}'.format(typ, str(err))) pass # move on to next type raise ValueError("Could not create an effect of type(s) %s from the given superket vector!" % (str(effect_type)))
def __init__(self, factor_povms, evotype="auto", state_space=None): dim = _np.product([povm.state_space.dim for povm in factor_povms]) if state_space is None: state_space = _statespace.default_space_for_dim(dim) else: assert ( state_space.dim == dim ), "`state_space` is incompatible with the product of the factors' spaces!" self.factorPOVMs = factor_povms for povm in self.factorPOVMs: if evotype == 'auto': evotype = povm._evotype else: assert(evotype == povm._evotype), \ "All factor povms must have the same evolution type" if evotype == 'auto': raise ValueError( "The 'auto' evotype can only be used when there is at least one factor!" ) items = [] # init as empty (lazy creation of members) self._factor_keys = tuple((list(povm.keys()) for povm in factor_povms)) self._factor_lbllens = [] for fkeys in self._factor_keys: assert (len(fkeys) > 0), "Each factor POVM must have at least one effect!" l = len( list(fkeys)[0]) # length of the first outcome label (a string) assert(all([len(elbl) == l for elbl in fkeys])), \ "All the effect labels for a given factor POVM must be the *same* length!" self._factor_lbllens.append(l) super(TensorProductPOVM, self).__init__(state_space, evotype, items) self.init_gpindices( ) # initialize gpindices and subm_rpindices from sub-members
def __init__(self, op_matrices, evotype="default", state_space=None, called_from_reduce=False, items=[]): self._readonly = False # until init is done if len(items) > 0: assert (op_matrices is None), "`items` was given when op_matrices != None" evotype = _Evotype.cast(evotype) self.param_ops = [] # first element is TP sum (MT), following #elements are fully-param'd (Mi-Mt) for i=0...n-2 #Note: when un-pickling using items arg, these members will # remain the above values, but *will* be set when state dict is copied # in (so unpickling works as desired) if op_matrices is not None: if isinstance(op_matrices, dict): matrix_list = [(k, v) for k, v in op_matrices.items() ] # gives definite ordering elif isinstance(op_matrices, list): matrix_list = op_matrices # assume it's is already an ordered (key,value) list else: raise ValueError("Invalid `op_matrices` arg of type %s" % type(op_matrices)) assert(len(matrix_list) > 0 or state_space is not None), \ "Must specify `state_space` when there are no instrument members!" state_space = _statespace.default_space_for_dim(matrix_list[0][1].shape[0]) if (state_space is None) \ else _statespace.StateSpace.cast(state_space) # Create gate objects that are used to parameterize this instrument MT_mx = sum([v for k, v in matrix_list ]) # sum-of-instrument-members matrix MT = _op.FullTPOp(MT_mx, evotype, state_space) self.param_ops.append(MT) dim = MT.dim for k, v in matrix_list[:-1]: Di = _op.FullArbitraryOp(v - MT_mx, evotype, state_space) assert (Di.dim == dim) self.param_ops.append(Di) #Create a TPInstrumentOp for each operation matrix # Note: TPInstrumentOp sets it's own parent and gpindices items = [(k, _TPInstrumentOp(self.param_ops, i)) for i, (k, v) in enumerate(matrix_list)] #DEBUG #print("POST INIT PARAM GATES:") #for i,v in enumerate(self.param_ops): # print(i,":\n",v) # #print("POST nINIT ITEMS:") #for k,v in items: # print(k,":\n",v) else: assert ( state_space is not None ), "`state_space` cannot be `None` when there are no members!" _collections.OrderedDict.__init__(self, items) _mm.ModelMember.__init__(self, state_space, evotype) if not called_from_reduce: # if called from reduce, gpindices are already initialized self.init_gpindices( ) # initialize our gpindices based on sub-members self._readonly = True
def __init__(self, member_ops, evotype=None, state_space=None, called_from_reduce=False, items=[]): self._readonly = False # until init is done if len(items) > 0: assert (member_ops is None), "`items` was given when op_matrices != None" if member_ops is not None: if isinstance(member_ops, dict): member_list = [(k, v) for k, v in member_ops.items() ] # gives definite ordering elif isinstance(member_ops, list): member_list = member_ops # assume it's is already an ordered (key,value) list else: raise ValueError("Invalid `member_ops` arg of type %s" % type(member_ops)) #Special case when we're given matrices: infer a default state space and evotype: if len(member_list) > 0 and not isinstance(member_list[0][1], _op.LinearOperator): if state_space is None: state_space = _statespace.default_space_for_dim( member_list[0][1].shape[0]) if evotype is None: evotype = _Evotype.cast('default') member_list = [(k, v if isinstance(v, _op.LinearOperator) else _op.FullArbitraryOp(v, evotype, state_space)) for k, v in member_list] assert(len(member_list) > 0 or state_space is not None), \ "Must specify `state_space` when there are no instrument members!" assert(len(member_list) > 0 or evotype is not None), \ "Must specify `evotype` when there are no instrument members!" evotype = _Evotype.cast(evotype) if ( evotype is not None) else member_list[0][1].evotype state_space = member_list[0][1].state_space if (state_space is None) \ else _statespace.StateSpace.cast(state_space) items = [] for k, member in member_list: assert(evotype == member.evotype), \ "All instrument members must have the same evolution type" assert(state_space.is_compatible_with(member.state_space)), \ "All instrument members must have compatible state spaces!" items.append((k, member)) else: if len( items ) > 0: # HACK so that OrderedDict.copy() works, which creates a new object with only items... if state_space is None: state_space = items[0][1].state_space if evotype is None: evotype = items[0][1].evotype assert ( state_space is not None ), "`state_space` cannot be `None` when there are no members!" assert (evotype is not None ), "`evotype` cannot be `None` when there are no members!" _collections.OrderedDict.__init__(self, items) _mm.ModelMember.__init__(self, state_space, evotype) if not called_from_reduce: # if called from reduce, gpindices are already initialized self.init_gpindices( ) # initialize our gpindices based on sub-members self._readonly = True
def _from_nice_serialization(cls, state): basis = _Basis.from_nice_serialization(state['basis']) return cls(_statespace.default_space_for_dim(state['state_space_dimension']), basis, state['evotype'])
def _from_nice_serialization(cls, state): #Note: this method assumes the (different) __init__ signature used by derived classes return cls(_statespace.default_space_for_dim(state['state_space_dimension']), state['evotype'])