def _success_dprob(self, circuit, param_slice, cache): """ todo """ assert(param_slice is None or _slct.length(param_slice) == len(self._paramvec)), \ "No support for derivatives with respect to a subset of model parameters yet!" pvec = self._paramvec**2 dpvec_dparams = 2 * self._paramvec if cache is None: cache = self._circuit_cache(circuit) one_over_2_width, all_inds_to_mult, all_inds_to_mult_cnt = cache sp = 1.0 - pvec successprob_all_ops = prod(sp[all_inds_to_mult]) deriv = _np.zeros(len(pvec), 'd') for i, n in enumerate(all_inds_to_mult_cnt): deriv[i] = n * successprob_all_ops / sp[i] * -1.0 # The circuit succeeds if all ops succeed, and has a random outcome otherwise. # successprob_circuit = successprob_all_ops + (1 - successprob_all_ops) / 2**width # = const + (1-1/2**width)*successprobs_all_ops deriv *= (1.0 - one_over_2_width) return deriv * dpvec_dparams
def _success_dprob(self, circuit, param_slice, cache): assert(param_slice is None or _slct.length(param_slice) == len(self._paramvec)), \ "No support for derivatives with respect to a subset of model parameters yet!" pvec = self._paramvec**2 dpvec_dparams = 2 * self._paramvec if cache is None: cache = self._circuit_cache(circuit) # p = product_layers(1 - alpha * (1 - prod_[inds4layer](1 - param))) * \ # (prod_[inds4LASTlayer](1 - param) - 1 / 2**width) # Note: indices cannot be repeated in a layer, i.e. either a given index appears one or zero times in inds4layer width, depth, alpha, one_over_2_width, inds_to_mult_by_layer = cache sp = 1.0 - pvec deriv = _np.zeros(len(pvec), 'd') nLayers = len(inds_to_mult_by_layer) lambda_per_layer = _np.empty(nLayers, 'd') for i, inds_to_mult in enumerate(inds_to_mult_by_layer[:-1]): lambda_per_layer[i] = 1 - alpha * (1 - prod(sp[inds_to_mult])) successprob_readout = prod(sp[inds_to_mult_by_layer[-1]]) lambda_per_layer[nLayers - 1] = successprob_readout - one_over_2_width lambda_all_layers = prod( lambda_per_layer) # includes readout factor as last layer #All layers except last for i, inds_to_mult in enumerate(inds_to_mult_by_layer[:-1]): lambda_all_but_current_layer = lambda_all_layers / lambda_per_layer[ i] # for each such ind, when we take deriv wrt this index, we need to differentiate this layer, etc. for ind in inds_to_mult: deriv[ind] += lambda_all_but_current_layer * alpha * \ (prod(sp[inds_to_mult]) / sp[ind]) * -1.0 # what if sp[ind] == 0? #Last layer lambda_all_but_current_layer = lambda_all_layers / lambda_per_layer[-1] for ind in inds_to_mult_by_layer[-1]: deriv[ind] += lambda_all_but_current_layer * ( successprob_readout / sp[ind]) * -1.0 # what if sp[ind] == 0? return deriv * dpvec_dparams
def _success_prob(self, circuit, cache): pvec = self._paramvec**2 if cache is None: cache = self._circuit_cache(circuit) all_inds_to_mult, all_inds_to_mult_cnt = cache # The success probability for all the operations (the entanglment fidelity for the gates) sp = 1.0 - pvec # The probability that every operation succeeds. successprob_circuit = prod(sp[all_inds_to_mult]) return successprob_circuit
def _success_prob(self, circuit, cache): pvec = self._paramvec**2 if cache is None: cache = self._circuit_cache(circuit) width, depth, alpha, one_over_2_width, inds_to_mult_by_layer = cache # The success probability for all the operations (the entanglment fidelity for the gates) sp = 1.0 - pvec # The depolarizing constant for the full sequence of twirled layers. lambda_all_layers = 1.0 for inds_to_mult in inds_to_mult_by_layer[:-1]: lambda_all_layers *= 1 - alpha * (1 - prod(sp[inds_to_mult])) # lambda_all_layers = prod([(1 - alpha * (1 - prod(sp[inds_to_mult]))) # for inds_to_mult in inds_to_mult_by_layer[:-1]]) # The readout success probability. successprob_readout = prod(sp[inds_to_mult_by_layer[-1]]) # THe success probability of the circuit. successprob_circuit = lambda_all_layers * ( successprob_readout - one_over_2_width) + one_over_2_width return successprob_circuit
def _success_dprob(self, circuit, param_slice, cache): """ todo """ assert(param_slice is None or _slct.length(param_slice) == len(self._paramvec)), \ "No support for derivatives with respect to a subset of model parameters yet!" pvec = self._paramvec**2 dpvec_dparams = 2 * self._paramvec if cache is None: cache = self._circuit_cache(circuit) width, depth, alpha, one_over_2_width, all_inds_to_mult, readout_inds_to_mult, all_inds_to_mult_cnt = cache sp = 1.0 - pvec lambda_ops = 1.0 - alpha * pvec deriv = _np.zeros(len(pvec), 'd') # The depolarizing constant for the full sequence of twirled gates. lambda_all_layers = prod(lambda_ops[all_inds_to_mult]) for i, n in enumerate(all_inds_to_mult_cnt): deriv[i] = n * lambda_all_layers / lambda_ops[ i] * -alpha # -alpha = d(lambda_ops/dparam) # The readout success probability. readout_deriv = _np.zeros(len(pvec), 'd') successprob_readout = prod(sp[readout_inds_to_mult]) for ind in readout_inds_to_mult: readout_deriv[ind] = (successprob_readout / sp[ind]) * -1.0 # what if sp[ind] == 0? # The success probability of the circuit. #successprob_circuit = lambda_all_layers * (successprob_readout - one_over_2_width) + one_over_2_width # product rule return (deriv * (successprob_readout - one_over_2_width) + lambda_all_layers * readout_deriv) * dpvec_dparams
def _success_prob(self, circuit, cache): """ todo """ pvec = self._paramvec**2 if cache is None: cache = self._circuit_cache(circuit) width, depth, alpha, one_over_2_width, all_inds_to_mult, readout_inds_to_mult, all_inds_to_mult_cnt = cache # The success probability for all the operations (the entanglment fidelity for the gates) sp = 1.0 - pvec # The 'lambda' for all gates (+ readout, which isn't used). lambda_ops = 1.0 - alpha * pvec # The depolarizing constant for the full sequence of twirled gates. lambda_all_layers = prod(lambda_ops[all_inds_to_mult]) # The readout success probability. successprob_readout = prod(sp[readout_inds_to_mult]) # THe success probability of the circuit. successprob_circuit = lambda_all_layers * ( successprob_readout - one_over_2_width) + one_over_2_width return successprob_circuit
def _success_prob(self, circuit, cache): pvec = self._paramvec**2 if cache is None: cache = self._circuit_cache(circuit) one_over_2_width, all_inds_to_mult, all_inds_to_mult_cnt = cache # The success probability for all the operations (the entanglment fidelity for the gates) sp = 1.0 - pvec # The probability that every operation succeeds. successprob_all_ops = prod(sp[all_inds_to_mult]) # The circuit succeeds if all ops succeed, and has a random outcome otherwise. successprob_circuit = successprob_all_ops + ( 1 - successprob_all_ops) * one_over_2_width return successprob_circuit
def _success_dprob(self, circuit, param_slice, cache): assert(param_slice is None or _slct.length(param_slice) == len(self._paramvec)), \ "No support for derivatives with respect to a subset of model parameters yet!" pvec = self._paramvec**2 dpvec_dparams = 2 * self._paramvec if cache is None: cache = self._circuit_cache(circuit) all_inds_to_mult, all_inds_to_mult_cnt = cache sp = 1.0 - pvec successprob_circuit = prod(sp[all_inds_to_mult]) deriv = _np.zeros(len(pvec), 'd') for i, n in enumerate(all_inds_to_mult_cnt): deriv[i] = n * successprob_circuit / sp[i] * -1.0 return deriv * dpvec_dparams