def repeat(self, n): """Creates an instruction with `gate` repeated `n` amount of times. Args: n (int): Number of times to repeat the instruction Returns: Instruction: Containing the definition. Raises: CircuitError: If n < 1. """ if int(n) != n or n < 1: raise CircuitError( "Repeat can only be called with strictly positive integer.") n = int(n) instruction = self._return_repeat(n) qargs = [] if self.num_qubits == 0 else QuantumRegister( self.num_qubits, 'q') cargs = [] if self.num_clbits == 0 else ClassicalRegister( self.num_clbits, 'c') instruction.definition = [(self, qargs[:], cargs[:])] * n return instruction
def repeat(self, n): """Creates an instruction with `gate` repeated `n` amount of times. Args: n (int): Number of times to repeat the instruction Returns: qiskit.circuit.Instruction: Containing the definition. Raises: CircuitError: If n < 1. """ if int(n) != n or n < 1: raise CircuitError( "Repeat can only be called with strictly positive integer.") n = int(n) instruction = self._return_repeat(n) qargs = [] if self.num_qubits == 0 else QuantumRegister( self.num_qubits, 'q') cargs = [] if self.num_clbits == 0 else ClassicalRegister( self.num_clbits, 'c') if instruction.definition is None: # pylint: disable=cyclic-import from qiskit import QuantumCircuit qc = QuantumCircuit() if qargs: qc.add_register(qargs) if cargs: qc.add_register(cargs) qc.data = [(self, qargs[:], cargs[:])] * n instruction.definition = qc return instruction
def _experiments_to_circuits(qobj): """Return a list of QuantumCircuit object(s) from a qobj Args: qobj (Qobj): The Qobj object to convert to QuantumCircuits Returns: list: A list of QuantumCircuit objects from the qobj """ if qobj.experiments: circuits = [] for x in qobj.experiments: quantum_registers = [ QuantumRegister(i[1], name=i[0]) for i in x.header.qreg_sizes ] classical_registers = [ ClassicalRegister(i[1], name=i[0]) for i in x.header.creg_sizes ] circuit = QuantumCircuit(*quantum_registers, *classical_registers, name=x.header.name) qreg_dict = {} creg_dict = {} for reg in quantum_registers: qreg_dict[reg.name] = reg for reg in classical_registers: creg_dict[reg.name] = reg for i in x.instructions: instr_method = getattr(circuit, i.name) qubits = [] try: for qubit in i.qubits: qubit_label = x.header.qubit_labels[qubit] qubits.append( qreg_dict[qubit_label[0]][qubit_label[1]]) except Exception: # pylint: disable=broad-except pass clbits = [] try: for clbit in i.memory: clbit_label = x.header.clbit_labels[clbit] clbits.append( creg_dict[clbit_label[0]][clbit_label[1]]) except Exception: # pylint: disable=broad-except pass params = [] try: params = i.params except Exception: # pylint: disable=broad-except pass if i.name in ['snapshot']: instr_method(*params) elif i.name == 'initialize': instr_method(params, qubits) else: instr_method(*params, *qubits, *clbits) circuits.append(circuit) return circuits return None
def construct_circuit( self, unitary: QuantumCircuit, state_preparation: QuantumCircuit, k: int, omega: float = 0, measurement: bool = False, ) -> QuantumCircuit: """Construct the kth iteration Quantum Phase Estimation circuit. For details of parameters, see Fig. 2 in https://arxiv.org/pdf/quant-ph/0610214.pdf. Args: unitary: The circuit representing the unitary operator whose eigenvalue (via phase) will be measured. state_preparation: The circuit that prepares the state whose eigenphase will be measured. If this parameter is omitted, no preparation circuit will be run and input state will be the all-zero state in the computational basis. k: the iteration idx. omega: the feedback angle. measurement: Boolean flag to indicate if measurement should be included in the circuit. Returns: QuantumCircuit: the quantum circuit per iteration """ k = self._num_iterations if k is None else k # The auxiliary (phase measurement) qubit phase_register = QuantumRegister(1, name="a") eigenstate_register = QuantumRegister(unitary.num_qubits, name="q") qc = QuantumCircuit(eigenstate_register) qc.add_register(phase_register) if isinstance(state_preparation, QuantumCircuit): qc.append(state_preparation, eigenstate_register) elif state_preparation is not None: qc += state_preparation.construct_circuit("circuit", eigenstate_register) # hadamard on phase_register[0] qc.h(phase_register[0]) # controlled-U # TODO: We may want to allow flexibility in how the power is computed # For example, it may be desirable to compute the power via Trotterization, if # we are doing Trotterization anyway. unitary_power = unitary.power(2**(k - 1)).control() qc = qc.compose(unitary_power, list(range(1, unitary.num_qubits + 1)) + [0]) qc.p(omega, phase_register[0]) # hadamard on phase_register[0] qc.h(phase_register[0]) if measurement: c = ClassicalRegister(1, name="c") qc.add_register(c) qc.measure(phase_register, c) return qc
def _add_measurement_if_required(self, pe_circuit): if not self._quantum_instance.is_statevector: # Measure only the evaluation qubits. regname = "meas" creg = ClassicalRegister(self._num_evaluation_qubits, regname) pe_circuit.add_register(creg) pe_circuit.barrier() pe_circuit.measure(range(self._num_evaluation_qubits), range(self._num_evaluation_qubits)) return circuit
def circuit_to_instruction(circuit): """Build an ``Instruction`` object from a ``QuantumCircuit``. The instruction is anonymous (not tied to a named quantum register), and so can be inserted into another circuit. The instruction will have the same string name as the circuit. Args: circuit (QuantumCircuit): the input circuit. Return: Instruction: an instruction equivalent to the action of the input circuit. Upon decomposition, this instruction will yield the components comprising the original circuit. """ instruction = Instruction( name=circuit.name, num_qubits=sum([qreg.size for qreg in circuit.qregs]), num_clbits=sum([creg.size for creg in circuit.cregs]), params=[]) instruction.control = None def find_bit_position(bit): """find the index of a given bit (Register, int) within a flat ordered list of bits of the circuit """ if isinstance(bit[0], QuantumRegister): ordered_regs = circuit.qregs else: ordered_regs = circuit.cregs reg_index = ordered_regs.index(bit[0]) return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit[1] definition = circuit.data.copy() if instruction.num_qubits > 0: q = QuantumRegister(instruction.num_qubits, 'q') if instruction.num_clbits > 0: c = ClassicalRegister(instruction.num_clbits, 'c') definition = list( map( lambda x: (x[0], list(map(lambda y: (q, find_bit_position(y)), x[1])), list(map(lambda y: (c, find_bit_position(y)), x[2]))), definition)) instruction.definition = definition return instruction
def extend_back(self, dag, edge_map=None): """Add `dag` at the end of `self`, using `edge_map`. """ edge_map = edge_map or {} for qreg in dag.qregs.values(): if qreg.name not in self.qregs: self.add_qreg(QuantumRegister(qreg.size, qreg.name)) edge_map.update([(qbit, qbit) for qbit in qreg if qbit not in edge_map]) for creg in dag.cregs.values(): if creg.name not in self.cregs: self.add_creg(ClassicalRegister(creg.size, creg.name)) edge_map.update([(cbit, cbit) for cbit in creg if cbit not in edge_map]) self.compose_back(dag, edge_map)
def __init__(self, graph): super().__init__() assert isinstance(graph, nx.Graph) or isinstance(graph, nx.DiGraph), \ ValueError("Graphs have to be networkx.Graph() or networkx.DiGraph()") self.graph = graph # Create a quantum register based on the number of nodes in G self.qreg = QuantumRegister(len(self.graph.nodes)) self.creg = ClassicalRegister(len(self.graph.nodes)) # Create a circuit using the quantum register self.circuit = QuantumCircuit(self.qreg, self.creg) # For each vertex, apply a Hadamard gate for vertex in self.graph.nodes: self.circuit.h(vertex) # For each edge e={x,y} apply a controlled-Z gate on its vertices for x, y in self.graph.edges: self.circuit.cz(x, y) # create a node dictionary from node to integer index of a qubit # in a Qiskit circuit self.node_dict = dict() for count, node in enumerate(self.graph.nodes): self.node_dict[node] = count
def power(circ, a, b, finalOut): #Because this is reversible/gate friendly memory blooms to say the least # Track Number of Qubits n = len(a) v = len(b) # Left 0 pad a, to satisfy multiplication function arguments aPad = AncillaRegister(2) circ.add_register(aPad) padAList = full_qr(aPad) aList = full_qr(a) a = aList + padAList # Create zero bits num_recycle = 2 permaZeros = [] if num_recycle > 0: permaZeros = AncillaRegister(num_recycle) #8 circ.add_register(permaZeros) permaZeros = full_qr(permaZeros) finalOut = full_qr(finalOut) + permaZeros # Create a register d for mults and init with state 1 d = AncillaRegister(len(finalOut)) # Unsure of where to Anciallas these circ.add_register(d) circ.x(d[0]) r = 2 # iterate through every qubit of b for i in range(0,v): # for every bit of b cmult(circ, [b[i]], a[:r], d[:r], finalOut[:r * 2], r) for swap_target in range(0, r*2): circ.cswap(b[i], d[swap_target], finalOut[swap_target]) circ.cx(b[i], finalOut[0]) r *= 2 cd = ClassicalRegister(len(d)) circ.add_register(cd) circ.measure(d, cd)
def _read_registers(file_obj, num_registers): registers = {"q": {}, "c": {}} for _reg in range(num_registers): register_raw = file_obj.read(REGISTER_SIZE) register = struct.unpack(REGISTER_PACK, register_raw) name = file_obj.read(register[2]).decode("utf8") REGISTER_ARRAY_PACK = "%sI" % register[1] bit_indices_raw = file_obj.read(struct.calcsize(REGISTER_ARRAY_PACK)) bit_indices = struct.unpack(REGISTER_ARRAY_PACK, bit_indices_raw) if register[0].decode("utf8") == "q": registers["q"][name] = {} registers["q"][name]["register"] = QuantumRegister( register[1], name) registers["q"][name]["index_map"] = dict( zip(bit_indices, registers["q"][name]["register"])) else: registers["c"][name] = {} registers["c"][name]["register"] = ClassicalRegister( register[1], name) registers["c"][name]["index_map"] = dict( zip(bit_indices, registers["c"][name]["register"])) return registers
def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None, label=None): """Build an ``Instruction`` object from a ``QuantumCircuit``. The instruction is anonymous (not tied to a named quantum register), and so can be inserted into another circuit. The instruction will have the same string name as the circuit. Args: circuit (QuantumCircuit): the input circuit. parameter_map (dict): For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the instruction. If None, existing circuit parameters will also parameterize the instruction. equivalence_library (EquivalenceLibrary): Optional equivalence library where the converted instruction will be registered. label (str): Optional instruction label. Raises: QiskitError: if parameter_map is not compatible with circuit Return: qiskit.circuit.Instruction: an instruction equivalent to the action of the input circuit. Upon decomposition, this instruction will yield the components comprising the original circuit. Example: .. jupyter-execute:: from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.converters import circuit_to_instruction %matplotlib inline q = QuantumRegister(3, 'q') c = ClassicalRegister(3, 'c') circ = QuantumCircuit(q, c) circ.h(q[0]) circ.cx(q[0], q[1]) circ.measure(q[0], c[0]) circ.rz(0.5, q[1]).c_if(c, 2) circuit_to_instruction(circ) """ # pylint: disable=cyclic-import from qiskit.circuit.quantumcircuit import QuantumCircuit if parameter_map is None: parameter_dict = {p: p for p in circuit.parameters} else: parameter_dict = circuit._unroll_param_dict(parameter_map) if parameter_dict.keys() != circuit.parameters: raise QiskitError( ( "parameter_map should map all circuit parameters. " "Circuit parameters: {}, parameter_map: {}" ).format(circuit.parameters, parameter_dict) ) instruction = Instruction( name=circuit.name, num_qubits=sum(qreg.size for qreg in circuit.qregs), num_clbits=sum(creg.size for creg in circuit.cregs), params=[*parameter_dict.values()], label=label, ) instruction.condition = None target = circuit.assign_parameters(parameter_dict, inplace=False) if equivalence_library is not None: equivalence_library.add_equivalence(instruction, target) definition = target.data regs = [] if instruction.num_qubits > 0: q = QuantumRegister(instruction.num_qubits, "q") regs.append(q) if instruction.num_clbits > 0: c = ClassicalRegister(instruction.num_clbits, "c") regs.append(c) qubit_map = {bit: q[idx] for idx, bit in enumerate(circuit.qubits)} clbit_map = {bit: c[idx] for idx, bit in enumerate(circuit.clbits)} definition = [ (inst, [qubit_map[y] for y in qargs], [clbit_map[y] for y in cargs]) for inst, qargs, cargs in definition ] # fix condition for rule in definition: condition = rule[0].condition if condition: reg, val = condition if isinstance(reg, Clbit): idx = 0 for creg in circuit.cregs: if reg not in creg: idx += creg.size else: cond_reg = creg break rule[0].condition = (c[idx + list(cond_reg).index(reg)], val) elif reg.size == c.size: rule[0].condition = (c, val) else: raise QiskitError( "Cannot convert condition in circuit with " "multiple classical registers to instruction" ) qc = QuantumCircuit(*regs, name=instruction.name) for instr, qargs, cargs in definition: qc._append(instr, qargs, cargs) if circuit.global_phase: qc.global_phase = circuit.global_phase instruction.definition = qc return instruction
def _experiments_to_circuits(qobj): """Return a list of QuantumCircuit object(s) from a qobj. Args: qobj (Qobj): The Qobj object to convert to QuantumCircuits Returns: list: A list of QuantumCircuit objects from the qobj """ if not qobj.experiments: return None circuits = [] for exp in qobj.experiments: quantum_registers = [QuantumRegister(i[1], name=i[0]) for i in exp.header.qreg_sizes] classical_registers = [ClassicalRegister(i[1], name=i[0]) for i in exp.header.creg_sizes] circuit = QuantumCircuit(*quantum_registers, *classical_registers, name=exp.header.name) qreg_dict = collections.OrderedDict() creg_dict = collections.OrderedDict() for reg in quantum_registers: qreg_dict[reg.name] = reg for reg in classical_registers: creg_dict[reg.name] = reg conditional = {} for i in exp.instructions: name = i.name qubits = [] params = getattr(i, "params", []) try: for qubit in i.qubits: qubit_label = exp.header.qubit_labels[qubit] qubits.append(qreg_dict[qubit_label[0]][qubit_label[1]]) except Exception: # pylint: disable=broad-except pass clbits = [] try: for clbit in i.memory: clbit_label = exp.header.clbit_labels[clbit] clbits.append(creg_dict[clbit_label[0]][clbit_label[1]]) except Exception: # pylint: disable=broad-except pass if hasattr(circuit, name): instr_method = getattr(circuit, name) if i.name in ["snapshot"]: _inst = instr_method( i.label, snapshot_type=i.snapshot_type, qubits=qubits, params=params ) elif i.name == "initialize": _inst = instr_method(params, qubits) elif i.name == "isometry": _inst = instr_method(*params, qubits, clbits) elif i.name in ["mcx", "mcu1", "mcp"]: _inst = instr_method(*params, qubits[:-1], qubits[-1], *clbits) else: _inst = instr_method(*params, *qubits, *clbits) elif name == "bfunc": conditional["value"] = int(i.val, 16) full_bit_size = sum(creg_dict[x].size for x in creg_dict) mask_map = {} raw_map = {} raw = [] for creg in creg_dict: size = creg_dict[creg].size reg_raw = [1] * size if not raw: raw = reg_raw else: for pos, val in enumerate(raw): if val == 1: raw[pos] = 0 raw = reg_raw + raw mask = [0] * (full_bit_size - len(raw)) + raw raw_map[creg] = mask mask_map[int("".join(str(x) for x in mask), 2)] = creg creg = mask_map[int(i.mask, 16)] conditional["register"] = creg_dict[creg] val = int(i.val, 16) mask = raw_map[creg] for j in reversed(mask): if j == 0: val = val >> 1 else: conditional["value"] = val break else: _inst = temp_opaque_instruction = Instruction( name=name, num_qubits=len(qubits), num_clbits=len(clbits), params=params ) circuit.append(temp_opaque_instruction, qubits, clbits) if conditional and name != "bfunc": _inst.c_if(conditional["register"], conditional["value"]) conditional = {} pulse_lib = qobj.config.pulse_library if hasattr(qobj.config, "pulse_library") else [] parametric_pulses = ( qobj.config.parametric_pulses if hasattr(qobj.config, "parametric_pulses") else [] ) # The dict update method did not work here; could investigate in the future if hasattr(qobj.config, "calibrations"): circuit.calibrations = dict( **circuit.calibrations, **_qobj_to_circuit_cals(qobj, pulse_lib, parametric_pulses) ) if hasattr(exp.config, "calibrations"): circuit.calibrations = dict( **circuit.calibrations, **_qobj_to_circuit_cals(exp, pulse_lib, parametric_pulses) ) circuits.append(circuit) return circuits
def run(self, dag): """Run the ConsolidateBlocks pass on `dag`. Iterate over each block and replace it with an equivalent Unitary on the same wires. """ if self.decomposer is None: return dag # compute ordered indices for the global circuit wires global_index_map = {wire: idx for idx, wire in enumerate(dag.qubits)} blocks = self.property_set["block_list"] basis_gate_name = self.decomposer.gate.name all_block_gates = set() for block in blocks: if len(block) == 1 and (self.basis_gates and block[0].name not in self.basis_gates): all_block_gates.add(block[0]) dag.substitute_node(block[0], UnitaryGate(block[0].op.to_matrix())) else: basis_count = 0 outside_basis = False block_qargs = set() block_cargs = set() for nd in block: block_qargs |= set(nd.qargs) if isinstance(nd, DAGOpNode) and nd.op.condition: block_cargs |= set(nd.op.condition[0]) all_block_gates.add(nd) q = QuantumRegister(len(block_qargs)) qc = QuantumCircuit(q) if block_cargs: c = ClassicalRegister(len(block_cargs)) qc.add_register(c) block_index_map = self._block_qargs_to_indices(block_qargs, global_index_map) for nd in block: if nd.op.name == basis_gate_name: basis_count += 1 if self.basis_gates and nd.op.name not in self.basis_gates: outside_basis = True qc.append(nd.op, [q[block_index_map[i]] for i in nd.qargs]) unitary = UnitaryGate(Operator(qc)) max_2q_depth = 20 # If depth > 20, there will be 1q gates to consolidate. if ( # pylint: disable=too-many-boolean-expressions self.force_consolidate or unitary.num_qubits > 2 or self.decomposer.num_basis_gates(unitary) < basis_count or len(block) > max_2q_depth or (self.basis_gates is not None and outside_basis) ): dag.replace_block_with_op(block, unitary, block_index_map, cycle_check=False) # If 1q runs are collected before consolidate those too runs = self.property_set["run_list"] or [] for run in runs: if run[0] in all_block_gates: continue if len(run) == 1 and self.basis_gates and run[0].name not in self.basis_gates: dag.substitute_node(run[0], UnitaryGate(run[0].op.to_matrix())) else: qubit = run[0].qargs[0] operator = run[0].op.to_matrix() already_in_block = False for gate in run[1:]: if gate in all_block_gates: already_in_block = True operator = gate.op.to_matrix().dot(operator) if already_in_block: continue unitary = UnitaryGate(operator) dag.replace_block_with_op(run, unitary, {qubit: 0}, cycle_check=False) return dag
def complete_meas_cal( qubit_list: List[int] = None, qr: Union[int, List["QuantumRegister"]] = None, cr: Union[int, 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 (or their size). If ``None``, one is created (default ``None``). cr: Classical registers (or their size). 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`. """ # Runtime imports to avoid circular imports causeed by QuantumInstance # getting initialized by imported utils/__init__ which is imported # by qiskit.circuit from qiskit.circuit.quantumregister import QuantumRegister from qiskit.circuit.classicalregister import ClassicalRegister from qiskit.circuit.exceptions import QiskitError 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 isinstance(qr, int): qr = QuantumRegister(qr) if qubit_list is None: qubit_list = range(len(qr)) if isinstance(cr, int): cr = ClassicalRegister(cr) 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 circuit_to_instruction(circuit, parameter_map=None): """Build an ``Instruction`` object from a ``QuantumCircuit``. The instruction is anonymous (not tied to a named quantum register), and so can be inserted into another circuit. The instruction will have the same string name as the circuit. Args: circuit (QuantumCircuit): the input circuit. parameter_map (dict): For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the instruction. If None, existing circuit parameters will also parameterize the instruction. Raises: QiskitError: if parameter_map is not compatible with circuit Return: Instruction: an instruction equivalent to the action of the input circuit. Upon decomposition, this instruction will yield the components comprising the original circuit. """ if parameter_map is None: parameter_map = {p: p for p in circuit.parameters} if parameter_map.keys() != circuit.parameters: raise QiskitError(('parameter_map should map all circuit parameters. ' 'Circuit parameters: {}, parameter_map: {}').format( circuit.parameters, parameter_map)) instruction = Instruction(name=circuit.name, num_qubits=sum([qreg.size for qreg in circuit.qregs]), num_clbits=sum([creg.size for creg in circuit.cregs]), params=sorted(parameter_map.values(), key=lambda p: p.name)) instruction.control = None def find_bit_position(bit): """find the index of a given bit (Register, int) within a flat ordered list of bits of the circuit """ if isinstance(bit[0], QuantumRegister): ordered_regs = circuit.qregs else: ordered_regs = circuit.cregs reg_index = ordered_regs.index(bit[0]) return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit[1] target = circuit.copy() target._substitute_parameters(parameter_map) definition = target.data if instruction.num_qubits > 0: q = QuantumRegister(instruction.num_qubits, 'q') if instruction.num_clbits > 0: c = ClassicalRegister(instruction.num_clbits, 'c') definition = list(map(lambda x: (x[0], list(map(lambda y: (q, find_bit_position(y)), x[1])), list(map(lambda y: (c, find_bit_position(y)), x[2]))), definition)) instruction.definition = definition return instruction
def test_x_measurement(self): """this will give you something different every time, so don't try to test the exact answer""" a = GraphState(self.G) a.x_measurement(a.qreg[0], a.creg[0]) assert isinstance(a.creg[0], type(Clbit(ClassicalRegister(3, 'c2'), 0)))
def tensored_meas_cal( mit_pattern: List[List[int]] = None, qr: Union[int, List["QuantumRegister"]] = None, cr: Union[int, List["ClassicalRegister"]] = None, circlabel: str = "", ) -> Tuple[List["QuantumCircuit"], List[List[int]]]: """ Return a list of calibration circuits Args: mit_pattern: Qubits on which to perform the measurement correction, divided to groups according to tensors. If `None` and `qr` is given then assumed to be performed over the entire `qr` as one group (default `None`). qr: A quantum register (or its size). If `None`, one is created (default `None`). cr: A classical register (or its size). 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 two QuantumCircuit objects containing the calibration circuits mit_pattern Additional Information: The returned circuits are named circlabel+cal_XXX where XXX is the basis state, e.g., cal_000 and cal_111. Pass the results of these circuits to the TensoredMeasurementFitter constructor. Raises: QiskitError: if both `mit_pattern` and `qr` are None. QiskitError: if a qubit appears more than once in `mit_pattern`. """ # Runtime imports to avoid circular imports causeed by QuantumInstance # getting initialized by imported utils/__init__ which is imported # by qiskit.circuit from qiskit.circuit.quantumregister import QuantumRegister from qiskit.circuit.classicalregister import ClassicalRegister from qiskit.circuit.quantumcircuit import QuantumCircuit from qiskit.circuit.exceptions import QiskitError if mit_pattern is None and qr is None: raise QiskitError("Must give one of mit_pattern or qr") if isinstance(qr, int): qr = QuantumRegister(qr) qubits_in_pattern = [] if mit_pattern is not None: for qubit_list in mit_pattern: for qubit in qubit_list: if qubit in qubits_in_pattern: raise QiskitError( "mit_pattern cannot contain multiple instances of the same qubit" ) qubits_in_pattern.append(qubit) # Create the registers if not already done if qr is None: qr = QuantumRegister(max(qubits_in_pattern) + 1) else: qubits_in_pattern = range(len(qr)) mit_pattern = [qubits_in_pattern] nqubits = len(qubits_in_pattern) # create classical bit registers if cr is None: cr = ClassicalRegister(nqubits) if isinstance(cr, int): cr = ClassicalRegister(cr) qubits_list_sizes = [len(qubit_list) for qubit_list in mit_pattern] nqubits = sum(qubits_list_sizes) size_of_largest_group = max(qubits_list_sizes) largest_labels = count_keys(size_of_largest_group) state_labels = [] for largest_state in largest_labels: basis_state = "" for list_size in qubits_list_sizes: basis_state = largest_state[:list_size] + basis_state state_labels.append(basis_state) cal_circuits = [] for basis_state in state_labels: qc_circuit = QuantumCircuit(qr, cr, name=f"{circlabel}cal_{basis_state}") end_index = nqubits for qubit_list, list_size in zip(mit_pattern, qubits_list_sizes): start_index = end_index - list_size substate = basis_state[start_index:end_index] for qind in range(list_size): if substate[list_size - qind - 1] == "1": qc_circuit.x(qr[qubit_list[qind]]) end_index = start_index qc_circuit.barrier(qr) # add measurements end_index = nqubits for qubit_list, list_size in zip(mit_pattern, qubits_list_sizes): for qind in range(list_size): qc_circuit.measure(qr[qubit_list[qind]], cr[nqubits - (end_index - qind)]) end_index -= list_size cal_circuits.append(qc_circuit) return cal_circuits, mit_pattern
def _experiments_to_circuits(qobj): """Return a list of QuantumCircuit object(s) from a qobj Args: qobj (Qobj): The Qobj object to convert to QuantumCircuits Returns: list: A list of QuantumCircuit objects from the qobj """ if qobj.experiments: circuits = [] for x in qobj.experiments: quantum_registers = [ QuantumRegister(i[1], name=i[0]) for i in x.header.qreg_sizes ] classical_registers = [ ClassicalRegister(i[1], name=i[0]) for i in x.header.creg_sizes ] circuit = QuantumCircuit(*quantum_registers, *classical_registers, name=x.header.name) qreg_dict = {} creg_dict = {} for reg in quantum_registers: qreg_dict[reg.name] = reg for reg in classical_registers: creg_dict[reg.name] = reg for i in x.instructions: name = i.name if i.name == 'id': name = 'iden' qubits = [] params = getattr(i, 'params', []) try: for qubit in i.qubits: qubit_label = x.header.qubit_labels[qubit] qubits.append( qreg_dict[qubit_label[0]][qubit_label[1]]) except Exception: # pylint: disable=broad-except pass clbits = [] try: for clbit in i.memory: clbit_label = x.header.clbit_labels[clbit] clbits.append( creg_dict[clbit_label[0]][clbit_label[1]]) except Exception: # pylint: disable=broad-except pass if hasattr(circuit, name): instr_method = getattr(circuit, name) if i.name in ['snapshot']: instr_method(i.label, snapshot_type=i.snapshot_type, qubits=qubits, params=params) elif i.name == 'initialize': instr_method(params, qubits) else: instr_method(*params, *qubits, *clbits) else: temp_opaque_instruction = Instruction( name=name, num_qubits=len(qubits), num_clbits=len(clbits), params=params) circuit.append(temp_opaque_instruction, qubits, clbits) circuits.append(circuit) return circuits return None
def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None): """Build an ``Instruction`` object from a ``QuantumCircuit``. The instruction is anonymous (not tied to a named quantum register), and so can be inserted into another circuit. The instruction will have the same string name as the circuit. Args: circuit (QuantumCircuit): the input circuit. parameter_map (dict): For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the instruction. If None, existing circuit parameters will also parameterize the instruction. equivalence_library (EquivalenceLibrary): Optional equivalence library where the converted instruction will be registered. Raises: QiskitError: if parameter_map is not compatible with circuit Return: qiskit.circuit.Instruction: an instruction equivalent to the action of the input circuit. Upon decomposition, this instruction will yield the components comprising the original circuit. Example: .. jupyter-execute:: from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.converters import circuit_to_instruction %matplotlib inline q = QuantumRegister(3, 'q') c = ClassicalRegister(3, 'c') circ = QuantumCircuit(q, c) circ.h(q[0]) circ.cx(q[0], q[1]) circ.measure(q[0], c[0]) circ.rz(0.5, q[1]).c_if(c, 2) circuit_to_instruction(circ) """ if parameter_map is None: parameter_dict = {p: p for p in circuit.parameters} else: parameter_dict = circuit._unroll_param_dict(parameter_map) if parameter_dict.keys() != circuit.parameters: raise QiskitError(('parameter_map should map all circuit parameters. ' 'Circuit parameters: {}, parameter_map: {}').format( circuit.parameters, parameter_dict)) instruction = Instruction( name=circuit.name, num_qubits=sum([qreg.size for qreg in circuit.qregs]), num_clbits=sum([creg.size for creg in circuit.cregs]), params=sorted(parameter_dict.values(), key=lambda p: p.name)) instruction.condition = None def find_bit_position(bit): """find the index of a given bit (Register, int) within a flat ordered list of bits of the circuit """ if isinstance(bit, Qubit): ordered_regs = circuit.qregs else: ordered_regs = circuit.cregs reg_index = ordered_regs.index(bit.register) return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit.index target = circuit.assign_parameters(parameter_dict, inplace=False) if equivalence_library is not None: equivalence_library.add_equivalence(instruction, target) definition = target.data if instruction.num_qubits > 0: q = QuantumRegister(instruction.num_qubits, 'q') if instruction.num_clbits > 0: c = ClassicalRegister(instruction.num_clbits, 'c') definition = list( map( lambda x: (x[0], list(map(lambda y: q[find_bit_position(y)], x[1])), list(map(lambda y: c[find_bit_position(y)], x[2]))), definition)) instruction.definition = definition return instruction
def _experiments_to_circuits(qobj): """Return a list of QuantumCircuit object(s) from a qobj. Args: qobj (Qobj): The Qobj object to convert to QuantumCircuits Returns: list: A list of QuantumCircuit objects from the qobj """ if qobj.experiments: circuits = [] for x in qobj.experiments: quantum_registers = [ QuantumRegister(i[1], name=i[0]) for i in x.header.qreg_sizes ] classical_registers = [ ClassicalRegister(i[1], name=i[0]) for i in x.header.creg_sizes ] circuit = QuantumCircuit(*quantum_registers, *classical_registers, name=x.header.name) qreg_dict = collections.OrderedDict() creg_dict = collections.OrderedDict() for reg in quantum_registers: qreg_dict[reg.name] = reg for reg in classical_registers: creg_dict[reg.name] = reg conditional = {} for i in x.instructions: name = i.name qubits = [] params = getattr(i, 'params', []) try: for qubit in i.qubits: qubit_label = x.header.qubit_labels[qubit] qubits.append( qreg_dict[qubit_label[0]][qubit_label[1]]) except Exception: # pylint: disable=broad-except pass clbits = [] try: for clbit in i.memory: clbit_label = x.header.clbit_labels[clbit] clbits.append( creg_dict[clbit_label[0]][clbit_label[1]]) except Exception: # pylint: disable=broad-except pass if hasattr(circuit, name): instr_method = getattr(circuit, name) if i.name in ['snapshot']: _inst = instr_method(i.label, snapshot_type=i.snapshot_type, qubits=qubits, params=params) elif i.name == 'initialize': _inst = instr_method(params, qubits) elif i.name == 'isometry': _inst = instr_method(*params, qubits, clbits) else: _inst = instr_method(*params, *qubits, *clbits) elif name == 'bfunc': conditional['value'] = int(i.val, 16) full_bit_size = sum([creg_dict[x].size for x in creg_dict]) mask_map = {} raw_map = {} raw = [] for creg in creg_dict: size = creg_dict[creg].size reg_raw = [1] * size if not raw: raw = reg_raw else: for pos, val in enumerate(raw): if val == 1: raw[pos] = 0 raw = reg_raw + raw mask = [0] * (full_bit_size - len(raw)) + raw raw_map[creg] = mask mask_map[int("".join(str(x) for x in mask), 2)] = creg creg = mask_map[int(i.mask, 16)] conditional['register'] = creg_dict[creg] val = int(i.val, 16) mask = raw_map[creg] for j in reversed(mask): if j == 0: val = val >> 1 else: conditional['value'] = val break else: _inst = temp_opaque_instruction = Instruction( name=name, num_qubits=len(qubits), num_clbits=len(clbits), params=params) circuit.append(temp_opaque_instruction, qubits, clbits) if conditional and name != 'bfunc': _inst.c_if(conditional['register'], conditional['value']) conditional = {} circuits.append(circuit) return circuits return None