def _validate_setup(self, skip=None): """Validate the current setup and raise an error if something misses to run.""" if skip is None: skip = {} required_attributes = {"quantum_instance", "optimizer"}.difference(skip) for attr in required_attributes: if getattr(self, attr, None) is None: raise ValueError(f"The {attr} cannot be None.") if self.num_timesteps is not None and self.num_timesteps <= 0: raise ValueError( f"The number of timesteps must be positive but is {self.num_timesteps}." ) if self.ansatz.num_parameters == 0: raise QiskitError( "The ansatz cannot have 0 parameters, otherwise it cannot be trained." ) if len(self.initial_parameters) != self.ansatz.num_parameters: raise QiskitError( f"Mismatching number of parameters in the ansatz ({self.ansatz.num_parameters}) " f"and the initial parameters ({len(self.initial_parameters)})." )
def FullAccreditation(self, confidence): """ This function computes the bound on variation distance based and the confidence interval desired. This protocol is from [1] and fully treats non-Markovian errors Args: confidence (float): number between 0 and 1 Returns: dict: dict of postselected target counts float: 1-norm bound from noiseless samples float: confidence Raises: QiskitError: If no runs are accepted or confidence is outside of 0,1 """ if self._Nacc == 0: raise QiskitError("ERROR: Variation distance requires" "at least one accepted run") if confidence > 1 or confidence < 0: raise QiskitError("ERROR: Confidence must be" "between 0 and 1") theta = np.sqrt(np.log(2/(1-confidence))/(2*self._Nruns)) if self._Nacc/self._Nruns > theta: bound = self._g*1.7/(self._Ntraps+1) bound = bound/(self._Nacc/self._Nruns-theta) bound = bound+1-self._g else: bound = 1 bound = min(bound, 1) return self._counts_accepted, bound, confidence
def _process_bit_id(self, node): """Process an Id or IndexedId node as a bit or register type. Return a list of tuples (Register,index). """ # pylint: disable=inconsistent-return-statements reg = None if node.name in self.dag.qregs: reg = self.dag.qregs[node.name] elif node.name in self.dag.cregs: reg = self.dag.cregs[node.name] else: raise QiskitError("expected qreg or creg name:", "line=%s" % node.line, "file=%s" % node.file) if node.type == "indexed_id": # An indexed bit or qubit return [(reg, node.index)] elif node.type == "id": # A qubit or qreg or creg if not self.bit_stack[-1]: # Global scope return [(reg, j) for j in range(reg.size)] else: # local scope if node.name in self.bit_stack[-1]: return [self.bit_stack[-1][node.name]] raise QiskitError("expected local bit name:", "line=%s" % node.line, "file=%s" % node.file) return None
def measure(self, qubit, cbit): """Measure quantum bit into classical bit (tuples). Args: qubit (QuantumRegister|tuple): quantum register cbit (ClassicalRegister|tuple): classical register Returns: qiskit.Instruction: the attached measure instruction. Raises: QiskitError: if qubit is not in this circuit or bad format; if cbit is not in this circuit or not creg. """ if isinstance(qubit, QuantumRegister) and isinstance(cbit, ClassicalRegister) \ and len(qubit) == len(cbit): instructions = InstructionSet() for i in range(qubit.size): instructions.add(self.measure((qubit, i), (cbit, i))) return instructions elif isinstance(qubit, QuantumRegister) and isinstance( cbit, ClassicalRegister) and len(qubit) != len(cbit): raise QiskitError( "qubit (%s) and cbit (%s) should have the same length" % (len(qubit), len(cbit))) elif not (isinstance(qubit, tuple) and isinstance(cbit, tuple)): raise QiskitError( "Both qubit <%s> and cbit <%s> should be Registers or formated as tuples. " "Hint: You can use subscript eg. cbit[0] to convert it into tuple." % (type(qubit).__name__, type(cbit).__name__)) self._check_qubit(qubit) self._check_creg(cbit[0]) cbit[0].check_range(cbit[1]) return self._attach(Measure(qubit, cbit, self))
def __iadd__(self, other): """Append a Result object to current Result object. Arg: other (Result): a Result object to append. Returns: Result: The current object with appended results. Raises: QiskitError: if the Results cannot be combined. """ warnings.warn( 'Result addition is deprecated and will be removed in ' 'version 0.7+.', DeprecationWarning) this_backend = self.backend_name other_backend = other.backend_name if this_backend != other_backend: raise QiskitError( 'Result objects from different backends cannot be combined.') if not self.success or not other.success: raise QiskitError( 'Can not combine a failed result with another result.') self.results.extend(other.results) return self
def preparation_circuit(self, op: str, qubit: Qubit) -> QuantumCircuit: """Return the preparation circuit on the given qubit Args: op: The name of the preparation operator qubit: The qubit on which to apply the preparation operator Raises: QiskitError: In case no preparation data is present in the basis or **qubit** is not Qubit ValueError: if **op** is not a n name of a preparation operator in the basis Returns: The preparation circuit """ # Error Checking if self.preparation is False: raise QiskitError("{} is not a preparation basis".format( self._name)) if not isinstance(qubit, Qubit): raise QiskitError('Input must be a qubit in a QuantumRegister') if op not in self._preparation_labels: msg = "Invalid {0} preparation operator label".format(self._name) error = "'{}' not in {}".format(op, self._preparation_labels) raise ValueError("{0}: {1}".format(msg, error)) return self._preparation_circuit(op, qubit)
def signals(self, signals: Union[VectorSignal, List[BaseSignal]]): """Set the signals.""" if signals is None: self._signal_params = None self._signals = None else: # if signals is a list, instantiate a VectorSignal if isinstance(signals, list): signals = VectorSignal.from_signal_list(signals) # if it isn't a VectorSignal by now, raise an error if not isinstance(signals, VectorSignal): raise QiskitError("signals specified in unaccepted format.") # verify signal length is same as operators if len(signals.carrier_freqs) != len(self.operators): raise QiskitError( """signals needs to have the same length as operators.""" ) # internal ops need to be reset if there is a cutoff frequency # and carrier_freqs has changed if self._signals is not None: if ( not np.allclose(self._signals.carrier_freqs, signals.carrier_freqs) and self._cutoff_freq is not None ): self._reset_internal_ops() self._signals = signals
def __init__(self, param, qargs, circ=None): """Create new initialize composite gate.""" num_qubits = math.log2(len(param)) # Check if param is a power of 2 if num_qubits == 0 or not num_qubits.is_integer(): raise QiskitError("Desired vector not a positive power of 2.") self.num_qubits = int(num_qubits) # Check if number of desired qubits agrees with available qubits if len(qargs) != self.num_qubits: raise QiskitError("Number of complex amplitudes do not correspond " "to the number of qubits.") # Check if probabilities (amplitudes squared) sum to 1 if not math.isclose(sum(np.absolute(param) ** 2), 1.0, abs_tol=_EPS): raise QiskitError("Sum of amplitudes-squared does not equal one.") super().__init__("init", param, qargs, circ) # call to generate the circuit that takes the desired vector to zero self.gates_to_uncompute() # remove zero rotations and double cnots self.optimize_gates() # invert the circuit to create the desired vector from zero (assuming # the qubits are in the zero state) self.inverse() # do not set the inverse flag, as this is the actual initialize gate # we just used inverse() as a method to obtain it self.inverse_flag = False
def _init_from_bool(self, z, x): """Construct pauli from boolean array. Args: z (numpy.ndarray): boolean, z vector x (numpy.ndarray): boolean, x vector Returns: Pauli: self Raises: QiskitError: if z or x are None or the length of z and x are different. """ if z is None: raise QiskitError("z vector must not be None.") if x is None: raise QiskitError("x vector must not be None.") if len(z) != len(x): raise QiskitError("length of z and x vectors must be " "the same. (z: {} vs x: {})".format(len(z), len(x))) z = _make_np_bool(z) x = _make_np_bool(x) self._z = z self._x = x return self
def _format_registers( *registers: Union[Qubit, QuantumRegister]) -> List[Qubit]: """Return a list of qubit QuantumRegister tuples. Args: registers: Any nonzero number of qubits or quantum registers, all unique Raises: QiskitError: If no qubits/registers were passed or non-unique qubits passed Returns: A flat list of all qubits passed. """ if not registers: raise QiskitError('No registers are being measured!') qubits = [] for tuple_element in registers: if isinstance(tuple_element, QuantumRegister): for j in range(tuple_element.size): qubits.append(tuple_element[j]) else: qubits.append(tuple_element) # Check registers are unique if len(qubits) != len(set(qubits)): raise QiskitError('Qubits to be measured are not unique!') return qubits
def measurement_circuit(self, op: str, qubit: Qubit, clbit: Clbit ) -> QuantumCircuit: """Return the measurement circuit on the given qubit and clbit Args: op: The name of the measurement operator qubit: The qubit on which to apply the measurement operator clbit: The classical bit that will hold the measurement result Raises: QiskitError: In case no measurement data is present in the basis or **qubit**/**clbit** are not Qubit/Clbit ValueError: if **op** is not a n name of a measurement operator in the basis Returns: The measurement circuit """ # Error Checking if self.measurement is False: raise QiskitError( "{} is not a measurement basis".format(self._name)) if not isinstance(qubit, Qubit): raise QiskitError('Input must be a qubit in a QuantumRegister') if not isinstance(clbit, Clbit): raise QiskitError('Input must be a bit in a ClassicalRegister') if op not in self._measurement_labels: msg = "Invalid {0} measurement operator label".format(self._name) error = "'{0}' != {1}".format(op, self._measurement_labels) raise ValueError("{0}: {1}".format(msg, error)) return self._measurement_circuit(op, qubit, clbit)
def single_protocol_run(self, results, postp_list, v_zero): """ DEPRECATED-Single protocol run of accreditation protocol Args: results (Result): results of the quantum job postp_list (list): list of strings used to post-process outputs v_zero (int): position of target Raises: QiskitError: If the number of circuits is inconsistent or if there are not at least 3 traps or if the data is not single shot """ self._Nruns = self._Nruns + 1 self.flag = 'accepted' # Check that correct number of traps is input if self._Nruns == 1: self._Ntraps = len(postp_list)-1 else: if len(postp_list)-1 != self._Ntraps: raise QiskitError("ERROR: Run protocol with the" "same number of traps") if self._Ntraps < 3: raise QiskitError("ERROR: run the protocol with at least 3 traps") allcounts = [] for ind, postp in enumerate(postp_list): # Classical postprocessing # check single shot and extract string counts = results.get_counts(ind) counts = QOTPCorrectCounts(counts, postp) shots = 0 countstring = None for countstring, val in counts.items(): shots += val if shots != 1 or countstring is None: raise QiskitError("ERROR: not single shot data") allcounts.append(countstring) for k, count in enumerate(allcounts): if k != v_zero: # Check if trap returns correct output if count != '0' * len(count): self.flag = 'rejected' else: output_target = count if self.flag == 'accepted': self._Nacc += 1 if output_target in self._counts_accepted.keys(): self._counts_accepted[output_target] += 1 else: self._counts_accepted[output_target] = 1 self.outputs = self._counts_accepted self.num_runs = self._Nruns self.N_acc = self._Nacc
def subset_fitter(self, qubit_sublist): """Return a fitter object that is a subset of the qubits in the original list. This is only a partial implementation of the ``subset_fitter`` method since only mitigation patterns of length 1 are supported. This corresponds to patterns of the form ``[[0], [1], [2], ...]``. Note however, that such patterns are a good first approximation to mitigate readout errors on large quantum circuits. Args: qubit_sublist (list): must be a subset of qubit_list Returns: TensoredMeasFitter: A new fitter that has the calibration for a subset of qubits Raises: QiskitError: If the calibration matrix is not initialized QiskitError: If the mit pattern is not a tensor of single-qubit measurement error mitigation. QiskitError: If a qubit in the given ``qubit_sublist`` is not in the list of qubits in the mit. pattern. """ if self._cal_matrices is None: raise QiskitError("Calibration matrices are not initialized.") if qubit_sublist is None: raise QiskitError("Qubit sublist must be specified.") if not all(len(tensor) == 1 for tensor in self._mit_pattern): raise QiskitError( f"Each element in the mit pattern should have length 1. Found {self._mit_pattern}." ) supported_qubits = set(tensor[0] for tensor in self._mit_pattern) for qubit in qubit_sublist: if qubit not in supported_qubits: raise QiskitError( f"Qubit {qubit} is not in the mit pattern {self._mit_pattern}." ) new_mit_pattern = [[idx] for idx in qubit_sublist] new_substate_labels_list = [ self._substate_labels_list[idx] for idx in qubit_sublist ] new_fitter = TensoredMeasFitter( results=None, mit_pattern=new_mit_pattern, substate_labels_list=new_substate_labels_list) new_fitter.cal_matrices = [ self._cal_matrices[idx] for idx in qubit_sublist ] return new_fitter
def mcrx(self, theta, q_controls, q_target, use_basis_gates=False): """ Apply Multiple-Controlled X rotation gate Args: self (QuantumCircuit): The QuantumCircuit object to apply the mcrx gate on. theta (float): angle theta q_controls (list(Qubit)): The list of control qubits q_target (Qubit): The target qubit use_basis_gates (bool): use u1, u2, u3, cx, id Raises: QiskitError: parameter errors """ # check controls if isinstance(q_controls, QuantumRegister): control_qubits = list(q_controls) elif isinstance(q_controls, list): control_qubits = q_controls else: raise QiskitError( 'The mcrx gate needs a list of qubits or a quantum register for controls.' ) # check target if isinstance(q_target, Qubit): target_qubit = q_target else: raise QiskitError('The mcrx gate needs a single qubit as target.') all_qubits = control_qubits + [target_qubit] self._check_qargs(all_qubits) self._check_dups(all_qubits) n_c = len(control_qubits) if n_c == 1: # cu3 _apply_cu3(self, theta, -pi / 2, pi / 2, control_qubits[0], target_qubit, use_basis_gates=use_basis_gates) else: theta_step = theta * (1 / (2**(n_c - 1))) _apply_mcu3_graycode(self, theta_step, -pi / 2, pi / 2, control_qubits, target_qubit, use_basis_gates=use_basis_gates)
def _verify_parameters(self, lengths, num_samples): """Verify input correctness, raise QiskitError if needed""" if any(length <= 0 for length in lengths): raise QiskitError( f"The lengths list {lengths} should only contain " "positive elements.") if len(set(lengths)) != len(lengths): raise QiskitError(f"The lengths list {lengths} should not contain " "duplicate elements.") if num_samples <= 0: raise QiskitError(f"The number of samples {num_samples} should " "be positive.")
def _delay_gate(self, qubit_state: dict, delay: float, t2hahn: float, frequency: float) -> dict: """ Apply delay gate to the qubit. From the delay time we can calculate the probability that an error has accrued. Args: qubit_state(dict): The state of the qubit before operating the gate. delay(float): The time in which there are no operation on the qubit. t2hahn(float): The T2 parameter of the backhand for probability calculation. frequency(float): The frequency of the qubit for phase calculation. Returns: dict: The state of the qubit after operating the gate. Raises: QiskitError: Raised if the frequency is 'None' or if the qubit isn't in the XY plane. """ if frequency is None: raise QiskitError( "Delay gate supported only if the qubit is on the XY plane.") new_qubit_state = qubit_state if qubit_state["XY plane"]: prob_noise = 1 - (np.exp(-delay / t2hahn)) if self._rng.random() < prob_noise: if self._rng.random() < 0.5: new_qubit_state = { "XY plane": False, "ZX plane": True, "Theta": 0, } else: new_qubit_state = { "XY plane": False, "ZX plane": True, "Theta": np.pi, } else: phase = frequency * delay new_theta = qubit_state["Theta"] + phase new_theta = new_theta % (2 * np.pi) new_qubit_state = { "XY plane": True, "ZX plane": False, "Theta": new_theta } else: if not isclose(qubit_state["Theta"], np.pi) and not isclose( qubit_state["Theta"], 0): raise QiskitError( "Delay gate supported only if the qubit is on the XY plane." ) return new_qubit_state
def _qubit_initialization(self, nqubits: int) -> List[dict]: """ Initialize the list of qubits state. If initialization error is provided to the backend it will use it to determine the initialized state. Args: nqubits(int): the number of qubits in the circuit. Returns: List[dict]: A list of dictionary which each dictionary contain the qubit state in the format {"XY plane": (bool), "ZX plane": (bool), "Theta": float} Raises: QiskitError: Raised if initialization_error type isn't 'None'', 'float' or a list of 'float' with length of number of the qubits. ValueError: Raised if the initialization error is negative. """ qubits_sates = [{} for _ in range(nqubits)] # Making an array with the initialization error for each qubit. initialization_error = self._initialization_error if isinstance(initialization_error, float) or initialization_error is None: initialization_error_arr = [initialization_error for _ in range(nqubits)] elif isinstance(initialization_error, list): if len(initialization_error) == 1: initialization_error_arr = [initialization_error[0] for _ in range(nqubits)] elif len(initialization_error) == nqubits: initialization_error_arr = initialization_error else: raise QiskitError( f"The length of the list {initialization_error} isn't the same as the number " "of qubits." ) else: raise QiskitError("Initialization error type isn't a list or float") for err in initialization_error_arr: if not isinstance(err, float): raise QiskitError("Initialization error type isn't a list or float") if err < 0: raise ValueError("Initialization error value can't be negative.") for qubit in range(nqubits): if initialization_error_arr[qubit] is not None and ( self._rng.random() < initialization_error_arr[qubit] ): qubits_sates[qubit] = {"XY plane": False, "ZX plane": True, "Theta": np.pi} else: qubits_sates[qubit] = { "XY plane": False, "ZX plane": True, "Theta": 0, } return qubits_sates
def ucz(self, angle_list, q_controls, q_target): """Attach a uniformly controlled (also called multiplexed gates) Rz rotation gate to a circuit. The decomposition is base on https://arxiv.org/pdf/quant-ph/0406176.pdf by Shende et al. Args: angle_list (list[numbers): list of (real) rotation angles [a_0,...,a_{2^k-1}] q_controls (QuantumRegister|list[Qubit]): list of k control qubits (or empty list if no controls). The control qubits are ordered according to their significance in increasing order: For example if q_controls=[q[1],q[2]] (with q = QuantumRegister(2)), the rotation Rz(a_0)is performed if q[1] and q[2] are in the state zero, the rotation Rz(a_1) is performed if q[1] is in the state one and q[2] is in the state zero, and so on q_target (QuantumRegister|Qubit): target qubit, where we act on with the single-qubit rotation gates Returns: QuantumCircuit: the uniformly controlled rotation gate is attached to the circuit. Raises: QiskitError: if the list number of control qubits does not correspond to the provided number of single-qubit unitaries; if an input is of the wrong type """ if isinstance(q_controls, QuantumRegister): q_controls = q_controls[:] if isinstance(q_target, QuantumRegister): q_target = q_target[:] if len(q_target) == 1: q_target = q_target[0] else: raise QiskitError( "The target qubit is a QuantumRegister containing" " more than one qubits.") # Check if q_controls has type "list" if not isinstance(angle_list, list): raise QiskitError("The angles must be provided as a list.") num_contr = math.log2(len(angle_list)) if num_contr < 0 or not num_contr.is_integer(): raise QiskitError( "The number of controlled rotation gates is not a non-negative" " power of 2.") # Check if number of control qubits does correspond to the number of rotations if num_contr != len(q_controls): raise QiskitError( "Number of controlled rotations does not correspond to the number" " of control-qubits.") return self.append(UCZ(angle_list), [q_target] + q_controls, [])
def plot_calibration(self, ax=None, show_plot=True): """ Plot the calibration matrix (2D color grid plot) Args: show_plot (bool): call plt.show() """ if self._cal_matrix is None: raise QiskitError("Cal matrix has not been set") if not HAS_MATPLOTLIB: raise ImportError('The function plot_rb_data needs matplotlib. ' 'Run "pip install matplotlib" before.') if ax is None: plt.figure() ax = plt.gca() axim = ax.matshow(self._cal_matrix, cmap=plt.cm.binary, clim=[0, 1]) ax.figure.colorbar(axim) if show_plot: plt.show()
def readout_fidelity(self, cal_index=0, label_list=None): """ Based on the results output the readout fidelity, which is the average of the diagonal entries in the calibration matrices Args: cal_index: readout fidelity of which sub cal? label_list (list of lists on states): Returns the average fidelity over of the groups of states. If None then each state used in the construction of the calibration matrices forms a group of size 1 Returns: readout fidelity (assignment fidelity) Additional Information: The on-diagonal elements of the calibration matrices are the probabilities of measuring state 'x' given preparation of state 'x' """ if self._cal_matrices is None: raise QiskitError("Cal matrix has not been set") if label_list is None: label_list = [[label] for label in self._substate_labels_list[cal_index]] tmp_fitter = CompleteMeasFitter(None, self._substate_labels_list[cal_index], circlabel='') tmp_fitter.cal_matrix = self.cal_matrices[cal_index] return tmp_fitter.readout_fidelity(label_list)
def plot_calibration(self, ax=None, show_plot=True): """ Plot the calibration matrix (2D color grid plot) Args: show_plot (bool): call plt.show() """ if self._cal_matrix is None: raise QiskitError("Cal matrix has not been set") if not HAS_MATPLOTLIB: raise ImportError('The function plot_rb_data needs matplotlib. ' 'Run "pip install matplotlib" before.') if ax is None: plt.figure() ax = plt.gca() axim = ax.matshow(self._cal_matrix, cmap=plt.cm.binary, clim=[0, 1]) ax.figure.colorbar(axim) ax.set_xlabel('Prepared State') ax.xaxis.set_label_position('top') ax.set_ylabel('Measured State') ax.set_xticks(np.arange(len(self._state_labels))) ax.set_yticks(np.arange(len(self._state_labels))) ax.set_xticklabels(self._state_labels) ax.set_yticklabels(self._state_labels) if show_plot: plt.show()
def _apply(self, si: BaseSignal, sq: BaseSignal) -> BaseSignal: """ Args: si: In phase signal sq: Quadrature signal. Returns: The up-converted signal. Raises: QiskitError: if the carriers frequencies of I and Q differ. """ # Check compatibility of the input signals if si.carrier_freq != sq.carrier_freq: raise QiskitError("IQ mixer requires the same sideband frequencies for I and Q.") phi_i, phi_q = si.phase, sq.phase wp, wm = self._lo + si.carrier_freq, self._lo - si.carrier_freq wp *= 2 * np.pi wm *= 2 * np.pi def mixer_func(t): """Function of the IQ mixer.""" osc_i = np.cos(wp * t + phi_i) + np.cos(wm * t + phi_i) osc_q = np.cos(wp * t + phi_q - np.pi / 2) + np.cos(wm * t + phi_q + np.pi / 2) return si.envelope_value(t) * osc_i / 2 + sq.envelope_value(t) * osc_q / 2 return Signal(mixer_func, carrier_freq=0, phase=0)
def from_label(cls, label): r"""Take pauli string to construct pauli. The qubit index of pauli label is q_{n-1} ... q_0. E.g., a pauli is $P_{n-1} \otimes ... \otimes P_0$ Args: label (str): pauli label Returns: Pauli: the constructed pauli Raises: QiskitError: invalid character in the label """ z = np.zeros(len(label), dtype=np.bool) x = np.zeros(len(label), dtype=np.bool) for i, char in enumerate(label): if char == 'X': x[-i - 1] = True elif char == 'Z': z[-i - 1] = True elif char == 'Y': z[-i - 1] = True x[-i - 1] = True elif char != 'I': raise QiskitError("Pauli string must be only consisted of 'I', 'X', " "'Y' or 'Z' but you have {}.".format(char)) return cls(z=z, x=x)
def _apply(self, signal: BaseSignal) -> BaseSignal: """ Applies a transformation on a signal, such as a convolution, low pass filter, etc. Once a convolution is applied the signal can longer have a carrier as the carrier is part of the signal value and gets convolved. Args: signal: A signal or list of signals to which the transfer function will be applied. Returns: signal: The transformed signal or list of signals. Raises: QiskitError: if the signal is not pwc. """ if isinstance(signal, PiecewiseConstant): # Perform a discrete time convolution. dt = signal.dt func_samples = Array([self._func(dt * i) for i in range(signal.duration)]) func_samples = func_samples / sum(func_samples) sig_samples = Array([signal.value(dt * i) for i in range(signal.duration)]) convoluted_samples = list(np.convolve(func_samples, sig_samples)) return PiecewiseConstant(dt, convoluted_samples, carrier_freq=0.0, phase=0.0) else: raise QiskitError("Transfer function not defined on input.")
def evaluate(self, time: float, in_frame_basis: bool = False) -> Array: """Evaluate the model in array format. Args: time: Time to evaluate the model in_frame_basis: Whether to evaluate in the basis in which the frame operator is diagonal Returns: Array: the evaluated model Raises: QiskitError: If model cannot be evaluated. """ if self._signals is None: raise QiskitError("""GeneratorModel cannot be evaluated without signals.""") sig_vals = self._signals.value(time) # evaluate the linear combination in the frame basis with cutoffs, # then map into the frame op_combo = self._evaluate_in_frame_basis_with_cutoffs(sig_vals) return self.frame.generator_into_frame( time, op_combo, operator_in_frame_basis=True, return_in_frame_basis=in_frame_basis )
def complete_meas_cal( qubit_list: List[int] = None, qr: List[QuantumRegister] = None, cr: List[ClassicalRegister] = None, circlabel: str = '') -> Tuple[List[QuantumCircuit], List[str]]: """ Return a list of measurement calibration circuits for the full Hilbert space. If the circuit contains :math:`n` qubits, then :math:`2^n` calibration circuits are created, each of which creates a basis state. Args: qubit_list: A list of qubits to perform the measurement correction on. If `None`, and qr is given then assumed to be performed over the entire qr. The calibration states will be labelled according to this ordering (default `None`). qr: Quantum registers. If `None`, one is created (default `None`). cr: Classical registers. If `None`, one is created(default `None`). circlabel: A string to add to the front of circuit names for unique identification(default ' '). Returns: A list of QuantumCircuit objects containing the calibration circuits. A list of calibration state labels. Additional Information: The returned circuits are named circlabel+cal_XXX where XXX is the basis state, e.g., cal_1001. Pass the results of these circuits to the CompleteMeasurementFitter constructor. Raises: QiskitError: if both `qubit_list` and `qr` are `None`. """ if qubit_list is None and qr is None: raise QiskitError("Must give one of a qubit_list or a qr") # Create the registers if not already done if qr is None: qr = QuantumRegister(max(qubit_list) + 1) if qubit_list is None: qubit_list = range(len(qr)) nqubits = len(qubit_list) # labels for 2**n qubit states state_labels = count_keys(nqubits) cal_circuits, _ = tensored_meas_cal([qubit_list], qr, cr, circlabel) return cal_circuits, state_labels
def benchmark_circuits(backend, circuits, shots=1): """Return average execution time for a list of circuits. Args: backend (Backend): A qiskit backend object. circuits list(QuantumCircuit): a list of quantum circuits. shots (int): Number of shots for each circuit. Returns float: The total execution time for all circuits divided by the number of circuits. Raises: QiskitError: If the simulation execution fails. """ qobj = qiskit.compile(circuits, backend, shots=shots) start_time = time.time() result = backend.run(qobj).result() end_time = time.time() if isinstance(circuits, QuantumCircuit): average_time = end_time - start_time else: average_time = (end_time - start_time) / len(circuits) if result.status != 'COMPLETED': raise QiskitError("Simulation failed. Status: " + result.status) return average_time
def measurement_matrix(self, label: str, outcome: Union[str, int] ) -> np.array: """Return the measurement matrix for a given measurement operator and expected outcome. Args: label: Name of the measurement element. outcome: The expected outcome: 0 or 1 or '0' or '1'. Raises: QiskitError: If the TomographyBasis has no measurement data ValueError: if **label** does not describe an element of the measurement data, or if **outcome** is not a valid outcome. Returns: The measurement matrix. """ if self.measurement is False: raise QiskitError("{} is not a measurement basis".format( self._name)) # Check input is valid for this basis if label not in self._measurement_labels: msg = "Invalid {0} measurement operator label".format(self._name) error = "'{}' not in {}".format(label, self._measurement_labels) raise ValueError("{0}: {1}".format(msg, error)) # Check outcome is valid for this measurement allowed_outcomes = [0, 1, '0', '1'] if outcome not in allowed_outcomes: error = "'{}' not in {}".format(outcome, allowed_outcomes) raise ValueError('Invalid measurement outcome: {}'.format(error)) return self._measurement_matrix(label, outcome)
def time_quantum_volume(self, qobj, noise_model): result = self.backend.run( qobj, noise_model=noise_model ).result() if result.status != 'COMPLETED': raise QiskitError("Simulation failed. Status: " + result.status)
def preparation_circuit(self, op, qubit): """Return the preparation circuits.""" # Error Checking if self.preparation is False: raise QiskitError("{} is not a preparation basis".format( self._name)) if not isinstance(qubit, Qubit): raise QiskitError('Input must be a qubit in a QuantumRegister') if op not in self._preparation_labels: msg = "Invalid {0} preparation operator label".format(self._name) error = "'{}' not in {}".format(op, self._preparation_labels) raise ValueError("{0}: {1}".format(msg, error)) return self._preparation_circuit(op, qubit)