コード例 #1
0
def bitFlipError(stateVector=[], error_probability=0.2):
    '''
        Quantum circuit to detect single bit flip errors.

        Note: Add compatibility of user given arbitrary state vector in the first qubit.
    '''
    q = QuantumRegister(3, name='q')
    c = ClassicalRegister(3, name='c')

    qc = QuantumCircuit(q, c, name='bit_flip_circuit')

    # Brings the 3 qubit system to the state (a*|000> + b*|111>). a=b=1/sqrt(2)
    if stateVector == []:
        qc.h(q[0])
    else:
        desired_vector = stateVector
        qc.initialize(desired_vector, [q[0]])
    qc.cx(q[0], q[1])
    qc.cx(q[0], q[2])
    # Random bit flip error with a probability of 0.2
    ind = random.randint(0, 2)
    if random.random() <= error_probability:
        print("Bit number {} flipped due to noise".format(ind + 1))
        qc.x(q[ind])

    ancilla = QuantumRegister(2, name='a')
    classical_ancilla = ClassicalRegister(2, name='ca')
    qc.add(ancilla)
    qc.add(classical_ancilla)

    qc.cx(q[0], ancilla[0])
    qc.cx(q[1], ancilla[0])
    qc.cx(q[0], ancilla[1])
    qc.cx(q[2], ancilla[1])

    qc.measure(ancilla, classical_ancilla)

    backend_sim = Aer.get_backend('qasm_simulator')
    job_sim = execute(qc, backend_sim)
    result_sim = job_sim.result()

    print("Finding bit flip error: ", result_sim)
    print(result_sim.get_counts(qc))

    error_bit = list(result_sim.get_counts().keys())[0].split()[0]
    if error_bit == '11':
        print("Bit-flip error in the first bit")
        qc.x(q[0])
    elif error_bit == '01':
        print("Bit-flip error in second bit")
        qc.x(q[1])
    elif error_bit == '10':
        print("Bit-flip error in third bit")
        qc.x(q[2])
    else:
        print("No bit-flip error in the code.")

    return q, c, qc
コード例 #2
0
def get_controlled_circuit(circuit, ctl_qubit, tgt_circuit=None, use_basis_gates=True):
    """
    Construct the controlled version of a given circuit.

    Args:
        circuit (QuantumCircuit) : the base circuit
        ctl_qubit (indexed QuantumRegister) : the control qubit to use
        tgt_circuit (QuantumCircuit) : the target controlled circuit to be modified in-place
        use_basis_gates (bool) : boolean flag to indicate whether or not only basis gates should be used

    Return:
        a QuantumCircuit object with the base circuit being controlled by ctl_qubit
    """
    if tgt_circuit is not None:
        qc = tgt_circuit
    else:
        qc = QuantumCircuit()

    # get all the qubits and clbits
    qregs = circuit.get_qregs()
    qubits = []
    for name in qregs:
        if not qc.has_register(qregs[name]):
            qc.add(qregs[name])
        qubits.extend(qregs[name])
    cregs = circuit.get_cregs()
    clbits = []
    for name in cregs:
        if not qc.has_register(cregs[name]):
            qc.add(cregs[name])
        clbits.extend(cregs[name])

    # get all operations from compiled circuit
    ops = transpiler.compile(
        circuit,
        Aer.get_backend('local_qasm_simulator'),
        basis_gates='u1,u2,u3,cx,id'
    )['circuits'][0]['compiled_circuit']['operations']

    # process all basis gates to add control
    if not qc.has_register(ctl_qubit[0]):
        qc.add(ctl_qubit[0])
    for op in ops:
        if op['name'] == 'id':
            apply_cu3(qc, 0, 0, 0, ctl_qubit, qubits[op['qubits'][0]], use_basis_gates=use_basis_gates)
        elif op['name'] == 'u1':
            apply_cu1(qc, *op['params'], ctl_qubit, qubits[op['qubits'][0]], use_basis_gates=use_basis_gates)
        elif op['name'] == 'u2':
            apply_cu3(qc, np.pi / 2, *op['params'], ctl_qubit, qubits[op['qubits'][0]], use_basis_gates=use_basis_gates)
        elif op['name'] == 'u3':
            apply_cu3(qc, *op['params'], ctl_qubit, qubits[op['qubits'][0]], use_basis_gates=use_basis_gates)
        elif op['name'] == 'cx':
            apply_ccx(qc, ctl_qubit, *[qubits[i] for i in op['qubits']], use_basis_gates=use_basis_gates)
        elif op['name'] == 'measure':
            qc.measure(qubits[op['qubits'][0]], clbits[op['clbits'][0]])
        else:
            raise RuntimeError('Unexpected operation {}.'.format(op['name']))

    return qc
コード例 #3
0
def Grover_search(arr):
    n = 3

    f_in = QuantumRegister(n)
    f_out = QuantumRegister(1)
    aux = QuantumRegister(n + 1)

    ans = ClassicalRegister(n)

    grover = QuantumCircuit()
    grover.add(f_in)
    grover.add(f_out)
    grover.add(aux)
    grover.add(ans)

    predefined_index = get_predefine_index(arr)

    input_state(grover, f_in, f_out, n)

    T = 2
    for t in range(T):
        oracle(grover, f_in, f_out, aux, n, predefined_index)
        inversion_about_average(grover, f_in, n)

    for j in range(n):
        grover.measure(f_in[j], ans[j])

    backend = Aer.get_backend('qasm_simulator')
    job = execute([grover], backend=backend, shots=1000)
    result = job.result()

    counts = result.get_counts(grover)
    inv = [(value, key) for key, value in counts.items()]
    outstr = str(max(inv)[1])
    ind = 0
    for i in range(len(outstr)):
        if outstr[i] == '1':
            ind = ind * 2 + 1
        else:
            ind = ind * 2
    # print(ind)
    # print(arr[ind])
    return ind
    #return arr[ind]
    #visualization.plot_histogram(counts)


# a = [1, 2, 0, 4, 5]
# Grover_search(a)
コード例 #4
0
    def add_circuits(self,
                     n_circuits,
                     do_measure=True,
                     basis=None,
                     basis_weights=None):
        """Adds circuits to program.

        Generates a circuit with a random number of operations in `basis`.
        Also adds a random number of measurements in
        [1,nQubits] to end of circuit.

        Args:
            n_circuits (int): Number of circuits to add.
            do_measure (bool): Whether to add measurements.
            basis (list(str) or None): List of op names. If None, basis
                is randomly chosen with unique ops in (2,7)
            basis_weights (list(float) or None): List of weights
                corresponding to indices in `basis`.
        Raises:
            AttributeError: if operation is not recognized.
        """
        if basis is None:
            basis = list(
                random.sample(self.op_signature.keys(), random.randint(2, 7)))
            basis_weights = [1. / len(basis)] * len(basis)
        if basis_weights is not None:
            assert len(basis) == len(basis_weights)
        uop_basis = basis[:]
        if basis_weights:
            uop_basis_weights = basis_weights[:]
        else:
            uop_basis_weights = None
        # remove barrier from uop basis if it is specified
        if 'barrier' in uop_basis:
            ind = uop_basis.index('barrier')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # remove measure from uop basis if it is specified
        if 'measure' in uop_basis:
            ind = uop_basis.index('measure')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # self.basis_gates = uop_basis
        self.basis_gates = basis
        self.circuit_name_list = []
        # TODO: replace choices with random.choices() when python 3.6 is
        # required.
        self.n_qubit_list = choices(range(self.min_qubits,
                                          self.max_qubits + 1),
                                    k=n_circuits)
        self.depth_list = choices(range(self.min_depth, self.max_depth + 1),
                                  k=n_circuits)
        for i_circuit in range(n_circuits):
            n_qubits = self.n_qubit_list[i_circuit]
            if self.min_regs_exceeds_nqubits(uop_basis, n_qubits):
                # no gate operation from this circuit can fit in the available
                # number of qubits.
                continue
            depth_cnt = self.depth_list[i_circuit]
            reg_pop = numpy.arange(1, n_qubits + 1)
            register_weights = reg_pop[::-1].astype(float)
            register_weights /= register_weights.sum()
            max_registers = numpy.random.choice(reg_pop, p=register_weights)
            reg_weight = numpy.ones(max_registers) / float(max_registers)
            reg_sizes = rand_register_sizes(n_qubits, reg_weight)
            n_registers = len(reg_sizes)
            circuit = QuantumCircuit()
            for i_size, size in enumerate(reg_sizes):
                cr_name = 'cr' + str(i_size)
                qr_name = 'qr' + str(i_size)
                creg = ClassicalRegister(cr_name, size)
                qreg = QuantumRegister(qr_name, size)
                circuit.add(qreg, creg)
            while depth_cnt > 0:
                # TODO: replace choices with random.choices() when python 3.6
                # is required.
                op_name = choices(basis, weights=basis_weights)[0]
                if hasattr(circuit, op_name):
                    operator = getattr(circuit, op_name)
                else:
                    raise AttributeError('operation \"{0}\"'
                                         ' not recognized'.format(op_name))
                n_regs = self.op_signature[op_name]['nregs']
                n_params = self.op_signature[op_name]['nparams']
                if n_regs == 0:  # this is a barrier or measure
                    n_regs = random.randint(1, n_qubits)
                if n_qubits >= n_regs:
                    # warning: assumes op function signature specifies
                    # op parameters before qubits
                    op_args = []
                    if n_params:
                        op_args = [random.random() for _ in range(n_params)]
                    if op_name == 'measure':
                        # if measure occurs here, assume it's to do a conditional
                        # randomly select a register to measure
                        ireg = random.randint(0, n_registers - 1)
                        qr_name = 'qr' + str(ireg)
                        cr_name = 'cr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        creg = circuit.regs[cr_name]
                        for qind in range(qreg.size):
                            operator(qreg[qind], creg[qind])
                        ifval = random.randint(0, (1 << qreg.size) - 1)
                        # TODO: replace choices with random.choices() when
                        # python 3.6 is required.
                        uop_name = choices(uop_basis,
                                           weights=uop_basis_weights)[0]
                        if hasattr(circuit, uop_name):
                            uop = getattr(circuit, uop_name)
                        else:
                            raise AttributeError(
                                'operation \"{0}\"'
                                ' not recognized'.format(uop_name))
                        unregs = self.op_signature[uop_name]['nregs']
                        unparams = self.op_signature[uop_name]['nparams']
                        if unregs == 0:  # this is a barrier or measure
                            unregs = random.randint(1, n_qubits)
                        if qreg.size >= unregs:
                            qind_list = random.sample(range(qreg.size), unregs)
                            uop_args = []
                            if unparams:
                                uop_args = [
                                    random.random() for _ in range(unparams)
                                ]
                            uop_args.extend([qreg[qind] for qind in qind_list])
                            uop(*uop_args).c_if(creg, ifval)
                        depth_cnt -= 1
                    elif op_name == 'barrier':
                        ireg = random.randint(0, n_registers - 1)
                        qr_name = 'qr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        bar_args = [(qreg, mi) for mi in range(qreg.size)]
                        operator(*bar_args)
                    else:
                        # select random register
                        ireg = random.randint(0, n_registers - 1)
                        qr_name = 'qr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        if qreg.size >= n_regs:
                            qind_list = random.sample(range(qreg.size), n_regs)
                            op_args.extend([qreg[qind] for qind in qind_list])
                            operator(*op_args)
                            depth_cnt -= 1
                        else:
                            break
            nmeasure = random.randint(1, n_qubits)
            m_list = random.sample(range(nmeasure), nmeasure)
            if do_measure:
                for qind in m_list:
                    rind = 0  # register index
                    cumtot = 0
                    while qind >= cumtot + circuit.regs['qr' + str(rind)].size:
                        cumtot += circuit.regs['qr' + str(rind)].size
                        rind += 1
                    qrind = int(qind - cumtot)
                    qreg = circuit.regs['qr' + str(rind)]
                    creg = circuit.regs['cr' + str(rind)]
                    circuit.measure(qreg[qrind], creg[qrind])
            self.circuit_list.append(circuit)
コード例 #5
0
    def add_circuits(self, nCircuits, doMeasure=True, basis=['u3', 'cx'],
                     basis_weights=None):
        """Adds circuits to program.

        Generates a circuit with a random number of operations in `basis`.
        Also adds a random number of measurements in
        [1,nQubits] to end of circuit.

        Args:
            nCircuits (int): Number of circuits to add.
            doMeasure (bool): Whether to add measurements.
            basis (list of str): List of op names.
            basis_weights (list of float or None): List of weights
                corresponding to indices in `basis`.
        """
        uop_basis = basis[:]
        if basis_weights:
            uop_basis_weights = basis_weights[:]
        else:
            uop_basis_weights = None
        # remove barrier from uop basis if it is specified
        if 'barrier' in uop_basis:
            ind = uop_basis.index('barrier')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # remove measure from uop basis if it is specified
        if 'measure' in uop_basis:
            ind = uop_basis.index('measure')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # self.basis_gates = uop_basis
        self.basis_gates = basis
        self.circuitNameList = []
        # TODO: replace choices with random.choices() when python 3.6 is
        # required.
        self.nQubit_list = choices(
            range(self.minQubits, self.maxQubits+1), k=nCircuits)
        self.depth_list = choices(
            range(self.minDepth, self.maxDepth+1), k=nCircuits)
        for iCircuit in range(nCircuits):
            nQubits = self.nQubit_list[iCircuit]
            depthCnt = self.depth_list[iCircuit]
            regpop = numpy.arange(1, nQubits+1)
            registerWeights = regpop[::-1].astype(float)
            registerWeights /= registerWeights.sum()
            maxRegisters = numpy.random.choice(regpop, p=registerWeights)
            regWeight = numpy.ones(maxRegisters) / float(maxRegisters)
            regSizes = rand_register_sizes(nQubits, regWeight)
            nRegisters = len(regSizes)
            circuit = QuantumCircuit()
            for isize, size in enumerate(regSizes):
                cr_name = 'cr' + str(isize)
                qr_name = 'qr' + str(isize)
                cr = ClassicalRegister(cr_name, size)
                qr = QuantumRegister(qr_name, size)
                circuit.add(qr, cr)
            while depthCnt > 0:
                # TODO: replace choices with random.choices() when python 3.6
                # is required.
                opName = choices(basis, weights=basis_weights)[0]
                if hasattr(circuit, opName):
                    op = getattr(circuit, opName)
                else:
                    raise AttributeError('operation \"{0}\"'
                                         ' not recognized'.format(opName))
                nregs = self.opSignature[opName]['nregs']
                nparams = self.opSignature[opName]['nparams']
                if nregs == 0:  # this is a barrier or measure
                    nregs = random.randint(1, nQubits)
                if nQubits >= nregs:
                    # warning: assumes op function signature specifies
                    # op parameters before qubits
                    op_args = []
                    if nparams:
                        op_args = [random.random() for p in range(nparams)]
                    if opName is 'measure':
                        # if measure occurs here, assume it's to do a conditional
                        # randomly select a register to measure
                        ireg = random.randint(0, nRegisters-1)
                        qr_name = 'qr' + str(ireg)
                        cr_name = 'cr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        creg = circuit.regs[cr_name]
                        for qind in range(qreg.size):
                            op(qreg[qind], creg[qind])
                        ifval = random.randint(0, (1 << qreg.size) - 1)
                        # TODO: replace choices with random.choices() when
                        # python 3.6 is required.
                        uopName = choices(uop_basis, weights=uop_basis_weights)[0]
                        if hasattr(circuit, uopName):
                            uop = getattr(circuit, uopName)
                        else:
                            raise AttributeError('operation \"{0}\"'
                                                 ' not recognized'.format(uopName))
                        unregs = self.opSignature[uopName]['nregs']
                        unparams = self.opSignature[uopName]['nparams']
                        if unregs == 0: # this is a barrier or measure
                            unregs = random.randint(1, nQubits)
                        if qreg.size >= unregs:
                            qindList = random.sample(range(qreg.size), unregs)
                            uop_args = []
                            if unparams:
                                uop_args = [random.random() for p in range(unparams)]
                            uop_args.extend([qreg[qind] for qind in qindList])
                            uop(*uop_args).c_if(creg, ifval)
                        depthCnt -= 1
                    elif opName is 'barrier':
                        ireg = random.randint(0, nRegisters-1)
                        qr_name = 'qr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        bar_args = [(qreg, mi) for mi in range(qreg.size)]
                        op(*bar_args)
                    else:
                        # select random register
                        ireg = random.randint(0, nRegisters-1)
                        qr_name = 'qr' + str(ireg)
                        try:
                            qreg = circuit.regs[qr_name]
                        except Exception as e:
                            print(e)
                            import pdb;pdb.set_trace()
                        if qreg.size >= nregs:
                            qindList = random.sample(range(qreg.size), nregs)
                            op_args.extend([qreg[qind] for qind in qindList])
                            op(*op_args)
                            depthCnt -= 1
            nmeasure = random.randint(1, nQubits)
            mList = random.sample(range(nmeasure), nmeasure)
            if doMeasure:
                for qind in mList:
                    rind = 0  # register index
                    cumtot = 0
                    while qind >= cumtot + circuit.regs['qr' + str(rind)].size:
                        cumtot += circuit.regs['qr' + str(rind)].size
                        rind += 1
                    qrind = int(qind - cumtot)
                    qreg = circuit.regs['qr'+str(rind)]
                    creg = circuit.regs['cr'+str(rind)]
                    try:
                        circuit.measure(qreg[qrind], creg[qrind])
                    except Exception as e:
                        print(e)
                        print(qrind)
                        import pdb;pdb.set_trace()
            self.circuit_list.append(circuit)
コード例 #6
0
    def add_circuits(self,
                     nCircuits,
                     doMeasure=True,
                     basis=['u3', 'cx'],
                     basis_weights=None):
        """Adds circuits to program.

        Generates a circuit with a random number of operations in `basis`. 
        Also adds a random number of measurements in
        [1,nQubits] to end of circuit.

        Args:
            nCircuits (int): Number of circuits to add.
            doMeasure (bool): Whether to add measurements.
            basis (list of str): List of op names.
            basis_weights (list of float or None): List of weights
                corresponding to indices in `basis`.
        """
        uop_basis = basis[:]
        if basis_weights:
            uop_basis_weights = basis_weights[:]
        else:
            uop_basis_weights = None
        # remove barrier from uop basis if it is specified
        if 'barrier' in uop_basis:
            ind = uop_basis.index('barrier')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # remove measure from uop basis if it is specified
        if 'measure' in uop_basis:
            ind = uop_basis.index('measure')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        #self.basis_gates = uop_basis
        self.basis_gates = basis
        self.circuitNameList = []
        # TODO: replace choices with random.choices() when python 3.6 is
        # required.
        self.nQubit_list = choices(range(self.minQubits, self.maxQubits + 1),
                                   k=nCircuits)
        self.depth_list = choices(range(self.minDepth, self.maxDepth + 1),
                                  k=nCircuits)
        for iCircuit in range(nCircuits):
            nQubits = self.nQubit_list[iCircuit]
            depthCnt = self.depth_list[iCircuit]
            regpop = numpy.arange(1, nQubits + 1)
            registerWeights = regpop[::-1].astype(float)
            registerWeights /= registerWeights.sum()
            maxRegisters = numpy.random.choice(regpop, p=registerWeights)
            regWeight = numpy.ones(maxRegisters) / float(maxRegisters)
            regSizes = rand_register_sizes(nQubits, regWeight)
            nRegisters = len(regSizes)
            circuit = QuantumCircuit()
            for isize, size in enumerate(regSizes):
                cr_name = 'cr' + str(isize)
                qr_name = 'qr' + str(isize)
                cr = ClassicalRegister(cr_name, size)
                qr = QuantumRegister(qr_name, size)
                circuit.add(qr, cr)
            while depthCnt > 0:
                # TODO: replace choices with random.choices() when python 3.6
                # is required.
                opName = choices(basis, weights=basis_weights)[0]
                if hasattr(circuit, opName):
                    op = getattr(circuit, opName)
                else:
                    raise AttributeError('operation \"{0}\"'
                                         ' not recognized'.format(opName))
                nregs = self.opSignature[opName]['nregs']
                nparams = self.opSignature[opName]['nparams']
                if nregs == 0:  # this is a barrier or measure
                    nregs = random.randint(1, nQubits)
                if nQubits >= nregs:
                    # warning: assumes op function signature specifies
                    # op parameters before qubits
                    op_args = []
                    if nparams:
                        op_args = [random.random() for p in range(nparams)]
                    if opName is 'measure':
                        # if measure occurs here, assume it's to do a conditional
                        # randomly select a register to measure
                        ireg = random.randint(0, nRegisters - 1)
                        qr_name = 'qr' + str(ireg)
                        cr_name = 'cr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        creg = circuit.regs[cr_name]
                        for qind in range(qreg.size):
                            op(qreg[qind], creg[qind])
                        ifval = random.randint(0, (1 << qreg.size) - 1)
                        # TODO: replace choices with random.choices() when
                        # python 3.6 is required.
                        uopName = choices(uop_basis,
                                          weights=uop_basis_weights)[0]
                        if hasattr(circuit, uopName):
                            uop = getattr(circuit, uopName)
                        else:
                            raise AttributeError(
                                'operation \"{0}\"'
                                ' not recognized'.format(uopName))
                        unregs = self.opSignature[uopName]['nregs']
                        unparams = self.opSignature[uopName]['nparams']
                        if unregs == 0:  # this is a barrier or measure
                            unregs = random.randint(1, nQubits)
                        if qreg.size >= unregs:
                            qindList = random.sample(range(qreg.size), unregs)
                            uop_args = []
                            if unparams:
                                uop_args = [
                                    random.random() for p in range(unparams)
                                ]
                            uop_args.extend([qreg[qind] for qind in qindList])
                            uop(*uop_args).c_if(creg, ifval)
                        depthCnt -= 1
                    elif opName is 'barrier':
                        ireg = random.randint(0, nRegisters - 1)
                        qr_name = 'qr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        bar_args = [(qreg, mi) for mi in range(qreg.size)]
                        op(*bar_args)
                    else:
                        # select random register
                        ireg = random.randint(0, nRegisters - 1)
                        qr_name = 'qr' + str(ireg)
                        try:
                            qreg = circuit.regs[qr_name]
                        except Exception as e:
                            print(e)
                            import pdb
                            pdb.set_trace()
                        if qreg.size >= nregs:
                            qindList = random.sample(range(qreg.size), nregs)
                            op_args.extend([qreg[qind] for qind in qindList])
                            op(*op_args)
                            depthCnt -= 1
            nmeasure = random.randint(1, nQubits)
            mList = random.sample(range(nmeasure), nmeasure)
            if doMeasure:
                for qind in mList:
                    rind = 0  # register index
                    cumtot = 0
                    while qind >= cumtot + circuit.regs['qr' + str(rind)].size:
                        cumtot += circuit.regs['qr' + str(rind)].size
                        rind += 1
                    qrind = int(qind - cumtot)
                    qreg = circuit.regs['qr' + str(rind)]
                    creg = circuit.regs['cr' + str(rind)]
                    try:
                        circuit.measure(qreg[qrind], creg[qrind])
                    except Exception as e:
                        print(e)
                        print(qrind)
                        import pdb
                        pdb.set_trace()
            self.circuit_list.append(circuit)
コード例 #7
0
def get_controlled_circuit(circuit,
                           ctl_qubit,
                           tgt_circuit=None,
                           use_basis_gates=True):
    """
    Construct the controlled version of a given circuit.

    Args:
        circuit (QuantumCircuit) : the base circuit
        ctl_qubit (indexed QuantumRegister) : the control qubit to use
        tgt_circuit (QuantumCircuit) : the target controlled circuit to be modified in-place
        use_basis_gates (bool) : boolean flag to indicate whether or not only basis gates should be used

    Return:
        a QuantumCircuit object with the base circuit being controlled by ctl_qubit
    """
    if tgt_circuit is not None:
        qc = tgt_circuit
    else:
        qc = QuantumCircuit()

    # get all the qubits and clbits
    qregs = circuit.qregs
    qubits = []
    for qreg in qregs:
        if not qc.has_register(qreg):
            qc.add_register(qreg)
        qubits.extend(qreg)
    cregs = circuit.cregs
    clbits = []
    for creg in cregs:
        if not qc.has_register(creg):
            qc.add_register(creg)
        clbits.extend(creg)

    # get all operations from compiled circuit
    unroller = Unroller(basis=['u1', 'u2', 'u3', 'cx', 'id'])
    pm = PassManager(passes=[unroller])
    ops = compiler.transpile(circuit,
                             BasicAer.get_backend('qasm_simulator'),
                             pass_manager=pm).data

    # process all basis gates to add control
    if not qc.has_register(ctl_qubit[0]):
        qc.add(ctl_qubit[0])
    for op in ops:
        if op[0].name == 'id':
            apply_cu3(qc,
                      0,
                      0,
                      0,
                      ctl_qubit,
                      op[1][0],
                      use_basis_gates=use_basis_gates)
        elif op[0].name == 'u1':
            apply_cu1(qc,
                      *op[0].params,
                      ctl_qubit,
                      op[1][0],
                      use_basis_gates=use_basis_gates)
        elif op[0].name == 'u2':
            apply_cu3(qc,
                      np.pi / 2,
                      *op[0].params,
                      ctl_qubit,
                      op[1][0],
                      use_basis_gates=use_basis_gates)
        elif op[0].name == 'u3':
            apply_cu3(qc,
                      *op[0].params,
                      ctl_qubit,
                      op[1][0],
                      use_basis_gates=use_basis_gates)
        elif op[0].name == 'cx':
            apply_ccx(qc, ctl_qubit, *op[1], use_basis_gates=use_basis_gates)
        elif op[0].name == 'measure':
            qc.measure(op[1], op[2])
        else:
            raise RuntimeError('Unexpected operation {}.'.format(op['name']))

    return qc
コード例 #8
0
    def add_circuits(self, n_circuits, do_measure=True, basis=None,
                     basis_weights=None):
        """Adds circuits to program.

        Generates a circuit with a random number of operations in `basis`.
        Also adds a random number of measurements in
        [1,nQubits] to end of circuit.

        Args:
            n_circuits (int): Number of circuits to add.
            do_measure (bool): Whether to add measurements.
            basis (list(str) or None): List of op names. If None, basis
                is randomly chosen with unique ops in (2,7)
            basis_weights (list(float) or None): List of weights
                corresponding to indices in `basis`.
        Raises:
            AttributeError: if operation is not recognized.
        """
        if basis is None:
            basis = list(random.sample(self.op_signature.keys(),
                                       random.randint(2, 7)))
            basis_weights = [1./len(basis)] * len(basis)
        if basis_weights is not None:
            assert len(basis) == len(basis_weights)
        uop_basis = basis[:]
        if basis_weights:
            uop_basis_weights = basis_weights[:]
        else:
            uop_basis_weights = None
        # remove barrier from uop basis if it is specified
        if 'barrier' in uop_basis:
            ind = uop_basis.index('barrier')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # remove measure from uop basis if it is specified
        if 'measure' in uop_basis:
            ind = uop_basis.index('measure')
            del uop_basis[ind]
            if uop_basis_weights:
                del uop_basis_weights[ind]
        # self.basis_gates = uop_basis
        self.basis_gates = basis
        self.circuit_name_list = []
        # TODO: replace choices with random.choices() when python 3.6 is
        # required.
        self.n_qubit_list = choices(
            range(self.min_qubits, self.max_qubits + 1), k=n_circuits)
        self.depth_list = choices(
            range(self.min_depth, self.max_depth + 1), k=n_circuits)
        for i_circuit in range(n_circuits):
            n_qubits = self.n_qubit_list[i_circuit]
            if self.min_regs_exceeds_nqubits(uop_basis, n_qubits):
                # no gate operation from this circuit can fit in the available
                # number of qubits.
                continue
            depth_cnt = self.depth_list[i_circuit]
            reg_pop = numpy.arange(1, n_qubits+1)
            register_weights = reg_pop[::-1].astype(float)
            register_weights /= register_weights.sum()
            max_registers = numpy.random.choice(reg_pop, p=register_weights)
            reg_weight = numpy.ones(max_registers) / float(max_registers)
            reg_sizes = rand_register_sizes(n_qubits, reg_weight)
            n_registers = len(reg_sizes)
            circuit = QuantumCircuit()
            for i_size, size in enumerate(reg_sizes):
                cr_name = 'cr' + str(i_size)
                qr_name = 'qr' + str(i_size)
                creg = ClassicalRegister(size, cr_name)
                qreg = QuantumRegister(size, qr_name)
                circuit.add(qreg, creg)
            while depth_cnt > 0:
                # TODO: replace choices with random.choices() when python 3.6
                # is required.
                op_name = choices(basis, weights=basis_weights)[0]
                if hasattr(circuit, op_name):
                    operator = getattr(circuit, op_name)
                else:
                    raise AttributeError('operation \"{0}\"'
                                         ' not recognized'.format(op_name))
                n_regs = self.op_signature[op_name]['nregs']
                n_params = self.op_signature[op_name]['nparams']
                if n_regs == 0:  # this is a barrier or measure
                    n_regs = random.randint(1, n_qubits)
                if n_qubits >= n_regs:
                    # warning: assumes op function signature specifies
                    # op parameters before qubits
                    op_args = []
                    if n_params:
                        op_args = [random.random() for _ in range(n_params)]
                    if op_name == 'measure':
                        # if measure occurs here, assume it's to do a conditional
                        # randomly select a register to measure
                        ireg = random.randint(0, n_registers-1)
                        qr_name = 'qr' + str(ireg)
                        cr_name = 'cr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        creg = circuit.regs[cr_name]
                        for qind in range(qreg.size):
                            operator(qreg[qind], creg[qind])
                        ifval = random.randint(0, (1 << qreg.size) - 1)
                        # TODO: replace choices with random.choices() when
                        # python 3.6 is required.
                        uop_name = choices(uop_basis, weights=uop_basis_weights)[0]
                        if hasattr(circuit, uop_name):
                            uop = getattr(circuit, uop_name)
                        else:
                            raise AttributeError('operation \"{0}\"'
                                                 ' not recognized'.format(uop_name))
                        unregs = self.op_signature[uop_name]['nregs']
                        unparams = self.op_signature[uop_name]['nparams']
                        if unregs == 0:  # this is a barrier or measure
                            unregs = random.randint(1, n_qubits)
                        if qreg.size >= unregs:
                            qind_list = random.sample(range(qreg.size), unregs)
                            uop_args = []
                            if unparams:
                                uop_args = [random.random() for _ in range(unparams)]
                            uop_args.extend([qreg[qind] for qind in qind_list])
                            uop(*uop_args).c_if(creg, ifval)
                        depth_cnt -= 1
                    elif op_name == 'barrier':
                        ireg = random.randint(0, n_registers-1)
                        qr_name = 'qr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        bar_args = [(qreg, mi) for mi in range(qreg.size)]
                        operator(*bar_args)
                    else:
                        # select random register
                        ireg = random.randint(0, n_registers-1)
                        qr_name = 'qr' + str(ireg)
                        qreg = circuit.regs[qr_name]
                        if qreg.size >= n_regs:
                            qind_list = random.sample(range(qreg.size), n_regs)
                            op_args.extend([qreg[qind] for qind in qind_list])
                            operator(*op_args)
                            depth_cnt -= 1
                        else:
                            break
            nmeasure = random.randint(1, n_qubits)
            m_list = random.sample(range(nmeasure), nmeasure)
            if do_measure:
                for qind in m_list:
                    rind = 0  # register index
                    cumtot = 0
                    while qind >= cumtot + circuit.regs['qr' + str(rind)].size:
                        cumtot += circuit.regs['qr' + str(rind)].size
                        rind += 1
                    qrind = int(qind - cumtot)
                    qreg = circuit.regs['qr'+str(rind)]
                    creg = circuit.regs['cr'+str(rind)]
                    circuit.measure(qreg[qrind], creg[qrind])
            self.circuit_list.append(circuit)
コード例 #9
0
class CircuitBackend(UnrollerBackend):
    """Backend for the unroller that produces a QuantumCircuit.

    By default, basis gates are the QX gates.
    """
    def __init__(self, basis=None):
        """Setup this backend.

        basis is a list of operation name strings.
        """
        super().__init__(basis)
        self.creg = None
        self.cval = None
        if basis:
            self.basis = basis
        else:
            self.basis = ["cx", "u1", "u2", "u3"]
        self.gates = {}
        self.listen = True
        self.in_gate = ""
        self.circuit = QuantumCircuit()

    def set_basis(self, basis):
        """Declare the set of user-defined gates to emit.

        basis is a list of operation name strings.
        """
        self.basis = basis

    def version(self, version):
        """Ignore the version string.

        v is a version number.
        """
        pass

    def new_qreg(self, name, size):
        """Create a new quantum register.

        name = name of the register
        sz = size of the register
        """
        assert size >= 0, "invalid qreg size"
        q_register = QuantumRegister(size, name)
        self.circuit.add(q_register)

    def new_creg(self, name, size):
        """Create a new classical register.

        name = name of the register
        sz = size of the register
        """
        assert size >= 0, "invalid creg size"
        c_register = ClassicalRegister(size, name)
        self.circuit.add(c_register)

    def define_gate(self, name, gatedata):
        """Define a new quantum gate.

        We don't check that the definition and name agree.

        name is a string.
        gatedata is the AST node for the gate.
        """
        self.gates[name] = gatedata

    def _map_qubit(self, qubit):
        """Map qubit tuple (regname, index) to (QuantumRegister, index)."""
        qregs = self.circuit.get_qregs()
        if qubit[0] not in qregs:
            raise BackendError("qreg %s does not exist" % qubit[0])
        return (qregs[qubit[0]], qubit[1])

    def _map_bit(self, bit):
        """Map bit tuple (regname, index) to (ClassicalRegister, index)."""
        cregs = self.circuit.get_cregs()
        if bit[0] not in cregs:
            raise BackendError("creg %s does not exist" % bit[0])
        return (cregs[bit[0]], bit[1])

    def _map_creg(self, creg):
        """Map creg name to ClassicalRegister."""
        cregs = self.circuit.get_cregs()
        if creg not in cregs:
            raise BackendError("creg %s does not exist" % creg)
        return cregs[creg]

    def u(self, arg, qubit, nested_scope=None):
        """Fundamental single qubit gate.

        arg is 3-tuple of Node expression objects.
        qubit is (regname,idx) tuple.
        nested_scope is a list of dictionaries mapping expression variables
        to Node expression objects in order of increasing nesting depth.
        """
        if self.listen:
            if "U" not in self.basis:
                self.basis.append("U")

            (theta, phi, lam) = list(map(lambda x: x.sym(nested_scope), arg))
            this_gate = self.circuit.u_base(theta, phi, lam,
                                            self._map_qubit(qubit))
            if self.creg is not None:
                this_gate.c_if(self._map_creg(self.creg), self.cval)

    def cx(self, qubit0, qubit1):
        """Fundamental two qubit gate.

        qubit0 is (regname,idx) tuple for the control qubit.
        qubit1 is (regname,idx) tuple for the target qubit.
        """
        if self.listen:
            if "CX" not in self.basis:
                self.basis.append("CX")
            this_gate = self.circuit.cx_base(self._map_qubit(qubit0),
                                             self._map_qubit(qubit1))
            if self.creg is not None:
                this_gate.c_if(self._map_creg(self.creg), self.cval)

    def measure(self, qubit, bit):
        """Measurement operation.

        qubit is (regname, idx) tuple for the input qubit.
        bit is (regname, idx) tuple for the output bit.
        """
        if "measure" not in self.basis:
            self.basis.append("measure")
        this_op = self.circuit.measure(self._map_qubit(qubit),
                                       self._map_bit(bit))
        if self.creg is not None:
            this_op.c_if(self._map_creg(self.creg), self.cval)

    def barrier(self, qubitlists):
        """Barrier instruction.

        qubitlists is a list of lists of (regname, idx) tuples.
        """
        if self.listen:
            if "barrier" not in self.basis:
                self.basis.append("barrier")
            flatlist = map(
                self._map_qubit,
                [qubit for qubitlist in qubitlists for qubit in qubitlist])
            self.circuit.barrier(*list(flatlist))

    def reset(self, qubit):
        """Reset instruction.

        qubit is a (regname, idx) tuple.
        """
        if "reset" not in self.basis:
            self.basis.append("reset")
        this_op = self.circuit.reset(self._map_qubit(qubit))
        if self.creg is not None:
            this_op.c_if(self._map_creg(self.creg), self.cval)

    def set_condition(self, creg, cval):
        """Attach a current condition.

        creg is a name string.
        cval is the integer value for the test.
        """
        self.creg = creg
        self.cval = cval

    def drop_condition(self):
        """Drop the current condition."""
        self.creg = None
        self.cval = None

    def start_gate(self, name, args, qubits, nested_scope=None):
        """Begin a custom gate.

        name is name string.
        args is list of Node expression objects.
        qubits is list of (regname, idx) tuples.
        nested_scope is a list of dictionaries mapping expression variables
        to Node expression objects in order of increasing nesting depth.
        """
        if self.listen and name not in self.basis \
           and self.gates[name]["opaque"]:
            raise BackendError("opaque gate %s not in basis" % name)
        if self.listen and name in self.basis:
            self.in_gate = name
            self.listen = False
            # Gate names mapped to number of arguments and qubits
            # and method to invoke on [args, qubits]
            lut = {
                "ccx": [(0, 3),
                        lambda x: self.circuit.ccx(x[1][0], x[1][1], x[1][2])],
                "ch": [(0, 2), lambda x: self.circuit.ch(x[1][0], x[1][1])],
                "crz": [(1, 2),
                        lambda x: self.circuit.crz(x[0][0], x[1][0], x[1][1])],
                "cswap":
                [(0, 3),
                 lambda x: self.circuit.cswap(x[1][0], x[1][1], x[1][2])],
                "cu1": [(1, 2),
                        lambda x: self.circuit.cu1(x[0][0], x[1][0], x[1][1])],
                "cu3": [(3, 2), lambda x: self.circuit.cu3(
                    x[0][0], x[0][1], x[0][2], x[1][0], x[1][1])],
                "cx": [(0, 2), lambda x: self.circuit.cx(x[1][0], x[1][1])],
                "cy": [(0, 2), lambda x: self.circuit.cy(x[1][0], x[1][1])],
                "cz": [(0, 2), lambda x: self.circuit.cz(x[1][0], x[1][1])],
                "swap": [(0, 2),
                         lambda x: self.circuit.swap(x[1][0], x[1][1])],
                "h": [(0, 1), lambda x: self.circuit.h(x[1][0])],
                "id": [(0, 1), lambda x: self.circuit.iden(x[1][0])],
                "rx": [(1, 1), lambda x: self.circuit.rx(x[0][0], x[1][0])],
                "ry": [(1, 1), lambda x: self.circuit.ry(x[0][0], x[1][0])],
                "rz": [(1, 1), lambda x: self.circuit.rz(x[0][0], x[1][0])],
                "s": [(0, 1), lambda x: self.circuit.s(x[1][0])],
                "sdg": [(0, 1), lambda x: self.circuit.s(x[1][0]).inverse()],
                "t": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()],
                "tdg": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()],
                "u1": [(1, 1), lambda x: self.circuit.u1(x[0][0], x[1][0])],
                "u2": [(2, 1),
                       lambda x: self.circuit.u2(x[0][0], x[0][1], x[1][0])],
                "u3":
                [(3, 1),
                 lambda x: self.circuit.u3(x[0][0], x[0][1], x[0][2], x[1][0])
                 ],
                "x": [(0, 1), lambda x: self.circuit.x(x[1][0])],
                "y": [(0, 1), lambda x: self.circuit.y(x[1][0])],
                "z": [(0, 1), lambda x: self.circuit.z(x[1][0])]
            }
            if name not in lut:
                raise BackendError("gate %s not in standard extensions" % name)
            gate_data = lut[name]
            if gate_data[0] != (len(args), len(qubits)):
                raise BackendError("gate %s signature (%d, %d) is " %
                                   (name, len(args), len(qubits)) +
                                   "incompatible with the standard " +
                                   "extensions")
            this_gate = gate_data[1]([
                list(map(lambda x: x.sym(nested_scope), args)),
                list(map(self._map_qubit, qubits))
            ])
            if self.creg is not None:
                this_gate.c_if(self._map_creg(self.creg), self.cval)

    def end_gate(self, name, args, qubits, nested_scope=None):
        """End a custom gate.

        name is name string.
        args is list of Node expression objects.
        qubits is list of (regname, idx) tuples.
        nested_scope is a list of dictionaries mapping expression variables
        to Node expression objects in order of increasing nesting depth.
        """
        if name == self.in_gate:
            self.in_gate = ""
            self.listen = True

    def get_output(self):
        """Return the QuantumCircuit object."""
        return self.circuit
コード例 #10
0
class CircuitBackend(UnrollerBackend):
    """Backend for the unroller that produces a QuantumCircuit.

    By default, basis gates are the QX gates.
    """

    def __init__(self, basis=None):
        """Setup this backend.

        basis is a list of operation name strings.
        """
        super().__init__(basis)
        self.creg = None
        self.cval = None
        if basis:
            self.basis = basis
        else:
            self.basis = ["cx", "u1", "u2", "u3"]
        self.gates = {}
        self.listen = True
        self.in_gate = ""
        self.circuit = QuantumCircuit()

    def set_basis(self, basis):
        """Declare the set of user-defined gates to emit.

        basis is a list of operation name strings.
        """
        self.basis = basis

    def version(self, version):
        """Ignore the version string.

        v is a version number.
        """
        pass

    def new_qreg(self, name, size):
        """Create a new quantum register.

        name = name of the register
        sz = size of the register
        """
        assert size >= 0, "invalid qreg size"
        q_register = QuantumRegister(size, name)
        self.circuit.add(q_register)

    def new_creg(self, name, size):
        """Create a new classical register.

        name = name of the register
        sz = size of the register
        """
        assert size >= 0, "invalid creg size"
        c_register = ClassicalRegister(size, name)
        self.circuit.add(c_register)

    def define_gate(self, name, gatedata):
        """Define a new quantum gate.

        We don't check that the definition and name agree.

        name is a string.
        gatedata is the AST node for the gate.
        """
        self.gates[name] = gatedata

    def _map_qubit(self, qubit):
        """Map qubit tuple (regname, index) to (QuantumRegister, index)."""
        qregs = self.circuit.get_qregs()
        if qubit[0] not in qregs:
            raise BackendError("qreg %s does not exist" % qubit[0])
        return (qregs[qubit[0]], qubit[1])

    def _map_bit(self, bit):
        """Map bit tuple (regname, index) to (ClassicalRegister, index)."""
        cregs = self.circuit.get_cregs()
        if bit[0] not in cregs:
            raise BackendError("creg %s does not exist" % bit[0])
        return (cregs[bit[0]], bit[1])

    def _map_creg(self, creg):
        """Map creg name to ClassicalRegister."""
        cregs = self.circuit.get_cregs()
        if creg not in cregs:
            raise BackendError("creg %s does not exist" % creg)
        return cregs[creg]

    def u(self, arg, qubit, nested_scope=None):
        """Fundamental single qubit gate.

        arg is 3-tuple of Node expression objects.
        qubit is (regname,idx) tuple.
        nested_scope is a list of dictionaries mapping expression variables
        to Node expression objects in order of increasing nesting depth.
        """
        if self.listen:
            if "U" not in self.basis:
                self.basis.append("U")

            (theta, phi, lam) = list(map(lambda x: x.sym(nested_scope), arg))
            this_gate = self.circuit.u_base(theta, phi, lam,
                                            self._map_qubit(qubit))
            if self.creg is not None:
                this_gate.c_if(self._map_creg(self.creg), self.cval)

    def cx(self, qubit0, qubit1):
        """Fundamental two qubit gate.

        qubit0 is (regname,idx) tuple for the control qubit.
        qubit1 is (regname,idx) tuple for the target qubit.
        """
        if self.listen:
            if "CX" not in self.basis:
                self.basis.append("CX")
            this_gate = self.circuit.cx_base(self._map_qubit(qubit0),
                                             self._map_qubit(qubit1))
            if self.creg is not None:
                this_gate.c_if(self._map_creg(self.creg), self.cval)

    def measure(self, qubit, bit):
        """Measurement operation.

        qubit is (regname, idx) tuple for the input qubit.
        bit is (regname, idx) tuple for the output bit.
        """
        if "measure" not in self.basis:
            self.basis.append("measure")
        this_op = self.circuit.measure(self._map_qubit(qubit),
                                       self._map_bit(bit))
        if self.creg is not None:
            this_op.c_if(self._map_creg(self.creg), self.cval)

    def barrier(self, qubitlists):
        """Barrier instruction.

        qubitlists is a list of lists of (regname, idx) tuples.
        """
        if self.listen:
            if "barrier" not in self.basis:
                self.basis.append("barrier")
            flatlist = map(self._map_qubit,
                           [qubit for qubitlist in qubitlists
                            for qubit in qubitlist])
            self.circuit.barrier(*list(flatlist))

    def reset(self, qubit):
        """Reset instruction.

        qubit is a (regname, idx) tuple.
        """
        if "reset" not in self.basis:
            self.basis.append("reset")
        this_op = self.circuit.reset(self._map_qubit(qubit))
        if self.creg is not None:
            this_op.c_if(self._map_creg(self.creg), self.cval)

    def set_condition(self, creg, cval):
        """Attach a current condition.

        creg is a name string.
        cval is the integer value for the test.
        """
        self.creg = creg
        self.cval = cval

    def drop_condition(self):
        """Drop the current condition."""
        self.creg = None
        self.cval = None

    def start_gate(self, name, args, qubits, nested_scope=None):
        """Begin a custom gate.

        name is name string.
        args is list of Node expression objects.
        qubits is list of (regname, idx) tuples.
        nested_scope is a list of dictionaries mapping expression variables
        to Node expression objects in order of increasing nesting depth.
        """
        if self.listen and name not in self.basis \
           and self.gates[name]["opaque"]:
            raise BackendError("opaque gate %s not in basis" % name)
        if self.listen and name in self.basis:
            self.in_gate = name
            self.listen = False
            # Gate names mapped to number of arguments and qubits
            # and method to invoke on [args, qubits]
            lut = {"ccx": [(0, 3),
                           lambda x: self.circuit.ccx(x[1][0], x[1][1],
                                                      x[1][2])],
                   "ch": [(0, 2),
                          lambda x: self.circuit.ch(x[1][0], x[1][1])],
                   "crz": [(1, 2),
                           lambda x: self.circuit.crz(x[0][0], x[1][0],
                                                      x[1][1])],
                   "cswap": [(0, 3),
                             lambda x: self.circuit.cswap(x[1][0],
                                                          x[1][1],
                                                          x[1][2])],
                   "cu1": [(1, 2),
                           lambda x: self.circuit.cu1(x[0][0], x[1][0],
                                                      x[1][1])],
                   "cu3": [(3, 2), lambda x: self.circuit.cu3(x[0][0],
                                                              x[0][1],
                                                              x[0][2],
                                                              x[1][0],
                                                              x[1][1])],
                   "cx": [(0, 2), lambda x: self.circuit.cx(x[1][0], x[1][1])],
                   "cy": [(0, 2), lambda x: self.circuit.cy(x[1][0], x[1][1])],
                   "cz": [(0, 2), lambda x: self.circuit.cz(x[1][0], x[1][1])],
                   "swap": [(0, 2), lambda x: self.circuit.swap(x[1][0], x[1][1])],
                   "h": [(0, 1), lambda x: self.circuit.h(x[1][0])],
                   "id": [(0, 1), lambda x: self.circuit.iden(x[1][0])],
                   "rx": [(1, 1), lambda x: self.circuit.rx(x[0][0], x[1][0])],
                   "ry": [(1, 1), lambda x: self.circuit.ry(x[0][0], x[1][0])],
                   "rz": [(1, 1), lambda x: self.circuit.rz(x[0][0], x[1][0])],
                   "s": [(0, 1), lambda x: self.circuit.s(x[1][0])],
                   "sdg": [(0, 1), lambda x: self.circuit.s(x[1][0]).inverse()],
                   "t": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()],
                   "tdg": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()],
                   "u1": [(1, 1), lambda x: self.circuit.u1(x[0][0], x[1][0])],
                   "u2": [(2, 1), lambda x: self.circuit.u2(x[0][0], x[0][1],
                                                            x[1][0])],
                   "u3": [(3, 1), lambda x: self.circuit.u3(x[0][0], x[0][1],
                                                            x[0][2], x[1][0])],
                   "x": [(0, 1), lambda x: self.circuit.x(x[1][0])],
                   "y": [(0, 1), lambda x: self.circuit.y(x[1][0])],
                   "z": [(0, 1), lambda x: self.circuit.z(x[1][0])]}
            if name not in lut:
                raise BackendError("gate %s not in standard extensions" %
                                   name)
            gate_data = lut[name]
            if gate_data[0] != (len(args), len(qubits)):
                raise BackendError("gate %s signature (%d, %d) is " %
                                   (name, len(args), len(qubits)) +
                                   "incompatible with the standard " +
                                   "extensions")
            this_gate = gate_data[1]([list(map(lambda x:
                                               x.sym(nested_scope), args)),
                                      list(map(self._map_qubit, qubits))])
            if self.creg is not None:
                this_gate.c_if(self._map_creg(self.creg), self.cval)

    def end_gate(self, name, args, qubits, nested_scope=None):
        """End a custom gate.

        name is name string.
        args is list of Node expression objects.
        qubits is list of (regname, idx) tuples.
        nested_scope is a list of dictionaries mapping expression variables
        to Node expression objects in order of increasing nesting depth.
        """
        if name == self.in_gate:
            self.in_gate = ""
            self.listen = True

    def get_output(self):
        """Return the QuantumCircuit object."""
        return self.circuit
コード例 #11
0
class Experiment:
    """ Experiment class for defining config, connecting to IBMQ and setting up quantum circuit. """
    def __init__(self, backend=None, shots=1024):
        try:
            register(Qconfig.APItoken, Qconfig.config['url'])
            print("Successfully connected to IBMQ.")
        except ConnectionError as e:
            print(
                "{}\n\nFailed to connect to IBMQ - only local simulations are possible."
                .format(e))
        self.backend = backend
        self.shots = shots
        self.register_initialised = False
        self.qc_initialised = False
        self.coupling_map = False
        self.results = False

    def connect_to_IBM(self, verify=False):
        """ Connect to IMB quantum experience using the class token value and config. """
        self.api = IBMQuantumExperience(Qconfig.APItoken,
                                        Qconfig.config,
                                        verify=verify)

    def create_registers(self, qubits=2, classical_bits=2):
        """ Create the quantum and classical registers with the specified number of bits. """
        if qubits != classical_bits:
            print(
                "Warning: number of quantum register bits does not equal classical "
            )
        self.q = QuantumRegister(qubits)
        self.c = [ClassicalRegister(1) for _ in range(classical_bits)]
        self.register_initialised = True

    def create_quantum_circuit(self):
        """ Initialise the quantum circuit if the quantum and classical registers have been initialised. """
        if self.register_initialised:
            self.qc = QuantumCircuit(self.q)
            for c in self.c:
                self.qc.add(c)
            self.qc_initialised = True
        else:
            print("Create quantum and classical registers first!")

    def bell_state(self, control_qubit=0, target_qubit=1):
        """ Create a bell state of specified qubits from an Experiment object. """
        if not self.qc_initialised:
            print("Initialise quantum circuit first.")
            return
        try:
            control_qubit = self.q[control_qubit]
            target_qubit = self.q[target_qubit]
        except:
            print("Initialising control and target qubits failed")
            return
        self.qc.h(control_qubit)
        self.qc.cx(control_qubit, target_qubit)
        self.qc.barrier(self.q)

    def single_qubit_gate(self, gate, qubit, angles=[0, 0, 0]):
        """ Adding a one qubit gate to the quantum circuit """
        gate = str(gate).lower()
        if not self.qc_initialised:
            print("Initialise quantum circuit first.")
            return
        try:
            qubit = self.q[qubit]
        except:
            print("Initialising control and target qubits failed")
            return
        if gate == 'h' or gate == 'hadamard':
            self.qc.h(qubit)
        elif gate == 'x':
            self.qc.x(qubit)
        elif gate == 'y':
            self.qc.y(qubit)
        elif gate == 'z':
            self.qc.z(qubit)
        elif gate == 'u1':
            self.qc.u1(angles[0], qubit)
        elif gate == 'u2':
            self.qc.u2(angles[0], angles[1], qubit)
        elif gate == 'u3':
            self.qc.u3(angles[0], angles[1], angles[2], qubit)
        else:
            print(
                "Not a valid single qubit gate. Gate not added to the circuit."
            )

    def two_qubit_gate(self, gate, control_qubit, target_qubit):
        """ Adding a two qubit gate to the quantum circuit """
        gate = str(gate).lower()
        if not self.qc_initialised:
            print("Initialise quantum circuit first.")
            return
        try:
            control_qubit = self.q[control_qubit]
            target_qubit = self.q[target_qubit]
        except:
            print("Initialising control and target qubits failed")
            return
        if gate == 'h' or gate == 'ch' or gate == 'control hadamard':
            self.qc.h(control_qubit, target_qubit)
        elif gate == 'x' or gate == 'cx' or gate == 'control x':
            self.qc.cx(control_qubit, target_qubit)
        elif gate == 'y' or gate == 'cy' or gate == 'control y':
            self.qc.cy(control_qubit, target_qubit)
        elif gate == 'z' or gate == 'cz' or gate == 'control z':
            self.qc.cz(control_qubit, target_qubit)
        else:
            print("Not a valid two qubit gate. Gate not added to the circuit.")

    def controlled_gate(self,
                        gate,
                        target_qubit,
                        control_bit,
                        control_value=1):
        """ Adding a two qubit gate to the quantum circuit """
        gate = str(gate).lower()
        if not self.qc_initialised:
            print("Initialise quantum circuit first.")
            return
        try:
            control = self.c[control_bit]
            qubit = self.q[target_qubit]
        except:
            print("Initialising control and target qubits failed")
            return
        if gate == 'h' or gate == 'ch' or gate == 'control hadamard':
            self.qc.h(qubit).c_if(control[0], control_value)
        elif gate == 'x' or gate == 'cx' or gate == 'control x':
            self.qc.x(qubit).c_if(control, control_value)
        elif gate == 'y' or gate == 'cy' or gate == 'control y':
            self.qc.y(qubit).c_if(control[0], control_value)
        elif gate == 'z' or gate == 'cz' or gate == 'control z':
            self.qc.z(qubit).c_if(control, control_value)
        else:
            print("Not a valid two qubit gate. Gate not added to the circuit.")

    def measure_gate(self, qubits=None, classical_bits=None):
        """ Add a measure gate to the quantum circuit of the Experiment class. 

            If you give a list of qubits, then give a list of controls where the 
            index matches where the qubit measurement is stored.        
        """
        if not qubits and not classical_bits:
            for i in self.c:
                self.qc.measure(self.q[i], i)
        elif qubits:
            for index, q in enumerate(qubits):
                self.qc.measure(self.q[q], self.c[classical_bits[index]][0])
                print("measured q: {}, c: {}".format(
                    self.q[q], self.c[classical_bits[index]]))

    def compile_and_run(self):
        """ Compile the quantum code and run on the selected backend. """
        if self.register_initialised and self.qc_initialised:
            print("Running on backend: {}".format(self.backend))
            if self.coupling_map:
                print("Using coupling map for {}...".format(self.backend))
                job = execute(self.qc,
                              backend=self.backend,
                              coupling_map=self.coupling_map,
                              shots=self.shots)
            else:
                job = execute(self.qc, backend=self.backend, shots=self.shots)
            result = job.result()
            self.data = result.get_counts(self.qc)
            self.results = True
            #print(result.get_data())
            #print(inspect.getmembers(result, predicate=inspect.ismethod))
            #print(result.get_ran_qasm(self.qc))
            print("Status: {} \nMeasurement result: {}".format(
                result, self.data))
        else:
            print("Initialise register and quantum circuit first.")

    def get_data(self):
        """ Return the result of the experiment in the form of a dictionary 
            with all combinations of measurements and the counts. 
        """
        if self.results:
            return self.data
        else:
            print("Compile and run the experiment first!")

    @staticmethod
    def IBMQ_register():
        try:
            register(Qconfig.APItoken, Qconfig.config['url'])
            print("Successfully connected to IBMQ.")
        except ConnectionError as e:
            print(
                "{}\n\nFailed to connect to IBMQ - only local simulations are possible."
                .format(e))
コード例 #12
0
exactly_1_3_sat_formula = [[1, 2, -3], [-1, -2, -3], [-1, 2, 3]]

# Define three quantum registers: 'f_in' is the search space (input
# to the function f), 'f_out' is bit used for the output of function
# f, aux are the auxiliary bits used by f to perform its
# computation.
f_in = QuantumRegister(n)
f_out = QuantumRegister(1)
aux = QuantumRegister(len(exactly_1_3_sat_formula) + 1)

# Define classical register for algorithm result
ans = ClassicalRegister(n)

# Define quantum circuit with above registers
grover = QuantumCircuit()
grover.add(f_in)
grover.add(f_out)
grover.add(aux)
grover.add(ans)

input_state(grover, f_in, f_out, n)
T = 2
for t in range(T):
    # Apply T full iterations
    black_box_u_f(grover, f_in, f_out, aux, n, exactly_1_3_sat_formula)
    inversion_about_average(grover, f_in, n)

# Measure the output register in the computational basis
for j in range(n):
    grover.measure(f_in[j], ans[j])