Example #1
0
    def _init_from_bool(self, z, x):
        """Construct pauli from boolean array.

        Args:
            z (numpy.ndarray): boolean, z vector
            x (numpy.ndarray): boolean, x vector

        Returns:
            Pauli: self

        Raises:
            QISKitError: if z or x are None or the length of z and x are different.
        """
        if z is None:
            raise QISKitError("z vector must not be None.")
        if x is None:
            raise QISKitError("x vector must not be None.")
        if len(z) != len(x):
            raise QISKitError("length of z and x vectors must be "
                              "the same. (z: {} vs x: {})".format(
                                  len(z), len(x)))

        z = _make_np_bool(z)
        x = _make_np_bool(x)
        self._z = z
        self._x = x

        return self
Example #2
0
    def __iadd__(self, other):
        """Append a Result object to current Result object.

        Arg:
            other (Result): a Result object to append.
        Returns:
            Result: The current object with appended results.
        Raises:
            QISKitError: if the Results cannot be combined.
        """
        warnings.warn(
            'Result addition is deprecated and will be removed in '
            'version 0.7+.', DeprecationWarning)

        this_backend = self.backend_name
        other_backend = other.backend_name
        if this_backend != other_backend:
            raise QISKitError(
                'Result objects from different backends cannot be combined.')

        if not self.success or not other.success:
            raise QISKitError(
                'Can not combine a failed result with another result.')

        self.results.extend(other.results)
        return self
Example #3
0
def measure(self, qubit, cbit):
    """Measure quantum bit into classical bit (tuples).
     Args:
        qubit (QuantumRegister|tuple): quantum register
        cbit (ClassicalRegister|tuple): classical register
    Returns:
        qiskit.Instruction: the attached measure instruction.
    Raises:
        QISKitError: if qubit is not in this circuit or bad format;
            if cbit is not in this circuit or not creg.
    """
    if isinstance(qubit, QuantumRegister) and isinstance(cbit, ClassicalRegister) \
            and len(qubit) == len(cbit):
        instructions = InstructionSet()
        for i in range(qubit.size):
            instructions.add(self.measure((qubit, i), (cbit, i)))
        return instructions
    elif isinstance(qubit, QuantumRegister) and isinstance(
            cbit, ClassicalRegister) and len(qubit) != len(cbit):
        raise QISKitError(
            "qubit (%s) and cbit (%s) should have the same length" %
            (len(qubit), len(cbit)))
    elif not (isinstance(qubit, tuple) and isinstance(cbit, tuple)):
        raise QISKitError(
            "Both qubit <%s> and cbit <%s> should be Registers or formated as tuples. "
            "Hint: You can use subscript eg. cbit[0] to convert it into tuple."
            % (type(qubit).__name__, type(cbit).__name__))

    self._check_qubit(qubit)
    self._check_creg(cbit[0])
    cbit[0].check_range(cbit[1])
    return self._attach(Measure(qubit, cbit, self))
Example #4
0
    def __init__(self, param, arg, circ=None):
        """Create new initialize composite gate."""
        num_qubits = math.log2(len(param))

        # Check if param is a power of 2
        if num_qubits == 0 or not num_qubits.is_integer():
            raise QISKitError("Desired vector not a positive power of 2.")

        self.num_qubits = int(num_qubits)

        # Check if number of desired qubits agrees with available qubits
        if len(arg) != self.num_qubits:
            raise QISKitError("Number of complex amplitudes do not correspond "
                              "to the number of qubits.")

        # Check if probabilities (amplitudes squared) sum to 1
        if not math.isclose(sum(numpy.absolute(param) ** 2), 1.0,
                            abs_tol=_EPS):
            raise QISKitError("Sum of amplitudes-squared does not equal one.")

        super().__init__("init", param, arg, circ)

        # call to generate the circuit that takes the desired vector to zero
        self.gates_to_uncompute()
        # remove zero rotations and double cnots
        self.optimize_gates()
        # invert the circuit to create the desired vector from zero (assuming
        # the qubits are in the zero state)
        self.inverse()
Example #5
0
    def _get_experiment(self, key=None):
        """Return an experiment from a given key.

        Args:
            key (str or QuantumCircuit or None): reference to a quantum circuit
                If None and there is only one circuit available, returns
                that one.

        Returns:
            ExperimentResult: an Experiment.

        Raises:
            QISKitError: if there is no data for the circuit, or an unhandled
                error occurred while fetching the data.
        """
        if self._is_error():
            raise QISKitError(str(self.status))

        if isinstance(key, QuantumCircuit):
            key = key.name
        elif key is None:
            if len(self.results) != 1:
                raise QISKitError(
                    "You have to select a circuit when there is more than "
                    "one available")
            else:
                key = list(self.results.keys())[0]
        key = str(key)

        return self.results[key]
Example #6
0
def _wait_for_job(job_id, api, wait=5, timeout=60):
    """Wait until all online ran circuits of a qobj are 'COMPLETED'.

    Args:
        job_id (list(str)):  is a list of id strings.
        api (IBMQuantumExperience.IBMQuantumExperience.IBMQuantumExperience):
            IBMQuantumExperience API connection
        wait (int):  is the time to wait between requests, in seconds
        timeout (int):  is how long we wait before failing, in seconds

    Returns:
        dict: A list of results that correspond to the jobids.

    Raises:
        QISKitError: job didn't return status or reported error in status
    """
    timer = 0
    job_result = api.get_job(job_id)
    if 'status' not in job_result:
        raise QISKitError("get_job didn't return status: %s" %
                          (pprint.pformat(job_result)))

    while job_result['status'] == 'RUNNING':
        if timer >= timeout:
            return {
                'job_id': job_id,
                'status': 'ERROR',
                'result': 'QISkit Time Out'
            }
        time.sleep(wait)
        timer += wait
        logger.info('status = %s (%d seconds)', job_result['status'], timer)
        job_result = api.get_job(job_id)

        if 'status' not in job_result:
            raise QISKitError("get_job didn't return status: %s" %
                              (pprint.pformat(job_result)))
        if (job_result['status'] == 'ERROR_CREATING_JOB'
                or job_result['status'] == 'ERROR_RUNNING_JOB'):
            return {
                'job_id': job_id,
                'status': 'ERROR',
                'result': job_result['status']
            }

    # Get the results
    job_result_return = []
    for index in range(len(job_result['qasms'])):
        job_result_return.append({
            'data': job_result['qasms'][index]['data'],
            'status': job_result['qasms'][index]['status']
        })
    return {
        'job_id': job_id,
        'status': job_result['status'],
        'result': job_result_return
    }
Example #7
0
def register(*args, provider_class=IBMQProvider, **kwargs):
    """
    Authenticate against an online backend provider.
    This is a factory method that returns the provider that gets registered.

    Note that if no parameters are passed, this method will try to
    automatically discover the credentials for IBMQ in the following places,
    in order::

        1. in the `Qconfig.py` file in the current working directory.
        2. in the environment variables.
        3. in the `qiskitrc` configuration file.

    Args:
        args (tuple): positional arguments passed to provider class initialization
        provider_class (BaseProvider): provider class
        kwargs (dict): keyword arguments passed to provider class initialization.
            For the IBMQProvider default this can include things such as:

                * token (str): The token used to register on the online backend such
                    as the quantum experience.
                * url (str): The url used for online backend such as the quantum
                    experience.
                * hub (str): The hub used for online backend.
                * group (str): The group used for online backend.
                * project (str): The project used for online backend.
                * proxies (dict): Proxy configuration for the API, as a dict with
                    'urls' and credential keys.
                * verify (bool): If False, ignores SSL certificates errors.

    Returns:
        BaseProvider: the provider instance that was just registered.

    Raises:
        QISKitError: if the provider could not be registered (e.g. due to
        conflict, or if no credentials were provided.)
    """
    # Try to autodiscover credentials if not passed.
    if not args and not kwargs and provider_class == IBMQProvider:
        kwargs = credentials.discover_credentials().get(
            credentials.get_account_name(IBMQProvider)) or {}
        if not kwargs:
            raise QISKitError(
                'No IBMQ credentials found. Please pass them explicitly or '
                'store them before calling register() with store_credentials()'
            )

    try:
        provider = provider_class(*args, **kwargs)
    except Exception as ex:
        raise QISKitError(
            "Couldn't instantiate provider! Error: {0}".format(ex))

    _DEFAULT_PROVIDER.add_provider(provider)
    return provider
Example #8
0
def _wait_for_job(jobid, api, wait=5, timeout=60, silent=True):
    """Wait until all online ran jobs are 'COMPLETED'.

    Args:
        jobid:  is a list of id strings.
        api (IBMQuantumExperience): IBMQuantumExperience API connection
        wait (int):  is the time to wait between requests, in seconds
        timeout (int):  is how long we wait before failing, in seconds
        silent (bool): is an option to print out the running information or
            not

    Returns:
        A list of results that correspond to the jobids.

    Raises:
        QISKitError:
    """
    timer = 0
    timeout_over = False
    job_result = api.get_job(jobid)
    if 'status' not in job_result:
        from pprint import pformat
        raise QISKitError("get_job didn't return status: %s" %
                          (pformat(job_result)))

    while job_result['status'] == 'RUNNING':
        if timer >= timeout:
            return {'status': 'ERROR', 'result': 'Time Out'}
        time.sleep(wait)
        timer += wait
        if not silent:
            print('status = %s (%d seconds)' % (job_result['status'], timer))
        job_result = api.get_job(jobid)

        if 'status' not in job_result:
            from pprint import pformat
            raise QISKitError("get_job didn't return status: %s" %
                              (pformat(job_result)))
        if job_result['status'] == 'ERROR_CREATING_JOB' or job_result[
                'status'] == 'ERROR_RUNNING_JOB':
            return {'status': 'ERROR', 'result': job_result['status']}

    # Get the results
    job_result_return = []
    for index in range(len(job_result['qasms'])):
        job_result_return.append({
            'data': job_result['qasms'][index]['data'],
            'status': job_result['qasms'][index]['status']
        })
    return {'status': job_result['status'], 'result': job_result_return}
Example #9
0
    def from_label(cls, label):
        r"""Take pauli string to construct pauli.

        The qubit index of pauli label is q_{n-1} ... q_0.
        E.g., a pauli is $P_{n-1} \otimes ... \otimes P_0$

        Args:
            label (str): pauli label

        Returns:
            Pauli: the constructed pauli

        Raises:
            QISKitError: invalid character in the label
        """
        z = np.zeros(len(label), dtype=np.bool)
        x = np.zeros(len(label), dtype=np.bool)
        for i, char in enumerate(label):
            if char == 'X':
                x[-i - 1] = True
            elif char == 'Z':
                z[-i - 1] = True
            elif char == 'Y':
                z[-i - 1] = True
                x[-i - 1] = True
            elif char != 'I':
                raise QISKitError(
                    "Pauli string must be only consisted of 'I', 'X', "
                    "'Y' or 'Z' but you have {}.".format(char))
        return cls(z=z, x=x)
Example #10
0
    def update_x(self, x, indices=None):
        """
        Update partial or entire x.

        Args:
            x (numpy.ndarray or list): to-be-updated x
            indices (numpy.ndarray or list or optional): to-be-updated qubit indices

        Returns:
            Pauli: self

        Raises:
            QISKitError: when updating whole x, the number of qubits must be the same.
        """
        x = _make_np_bool(x)
        if indices is None:
            if len(self._x) != len(x):
                raise QISKitError(
                    "During updating whole x, you can not change "
                    "the number of qubits.")
            self._x = x
        else:
            if not isinstance(indices, list) and not isinstance(
                    indices, np.ndarray):
                indices = [indices]
            for p, idx in enumerate(indices):
                self._x[idx] = x[p]

        return self
Example #11
0
    def update_z(self, z, indices=None):
        """
        Update partial or entire z.

        Args:
            z (numpy.ndarray or list): to-be-updated z
            indices (numpy.ndarray or list or optional): to-be-updated qubit indices

        Returns:
            Pauli: self

        Raises:
            QISKitError: when updating whole z, the number of qubits must be the same.
        """
        z = _make_np_bool(z)
        if indices is None:
            if len(self._z) != len(z):
                raise QISKitError("During updating whole z, you can not "
                                  "change the number of qubits.")
            self._z = z
        else:
            if not isinstance(indices, list) and not isinstance(
                    indices, np.ndarray):
                indices = [indices]
            for p, idx in enumerate(indices):
                self._z[idx] = z[p]

        return self
Example #12
0
def register(*args, provider_class=IBMQProvider, **kwargs):
    """
    Authenticate against an online backend provider.
    This is a factory method that returns the provider that gets registered.

    Args:
        args (tuple): positional arguments passed to provider class initialization
        provider_class (BaseProvider): provider class
        kwargs (dict): keyword arguments passed to provider class initialization.
            For the IBMQProvider default this can include things such as;
            token (str): The token used to register on the online backend such
                as the quantum experience.
            url (str): The url used for online backend such as the quantum
                experience.
            hub (str): The hub used for online backend.
            group (str): The group used for online backend.
            project (str): The project used for online backend.
            proxies (dict): Proxy configuration for the API, as a dict with
                'urls' and credential keys.
            verify (bool): If False, ignores SSL certificates errors.

    Returns:
        BaseProvider: the provider instance that was just registered.

    Raises:
        QISKitError: if the provider could not be registered
        (e.g. due to conflict)
    """
    try:
        provider = provider_class(*args, **kwargs)
    except Exception as ex:
        raise QISKitError("Couldn't instance provider!. Error: {0}".format(ex))

    _DEFAULT_PROVIDER.add_provider(provider)
    return provider
Example #13
0
    def add_provider(self, provider):
        """
        Add a new provider to the list of known providers.

        Args:
            provider (BaseProvider): Provider instance.

        Returns:
            BaseProvider: the provider instance.

        Raises:
            QISKitError: if trying to add a provider identical to one already registered
        """
        # Check for backend name clashes, emitting a warning.
        current_backends = {str(backend) for backend in self.available_backends()}
        added_backends = {str(backend) for backend in provider.available_backends()}
        common_backends = added_backends.intersection(current_backends)

        # checks for equality of provider instances, based on the __eq__ method
        if provider not in self.providers:
            self.providers.append(provider)
        else:
            raise QISKitError("The same provider has already been registered!")

        if common_backends:
            logger.warning(
                'The backend names "%s" of this provider are already in use. '
                'Refer to documentation for `available_backends()` and `unregister()`.',
                list(common_backends))

        return provider
Example #14
0
    def remove_provider(self, provider_name):
        """
        Remove a provider from the list of known providers.

        Args:
            provider_name (str): name of the provider to be removed.

        Raises:
            QISKitError: if the provider name is not valid.
        """
        if provider_name == 'local':
            raise QISKitError("Cannot unregister 'local' provider.")
        try:
            self.providers.pop(provider_name)
        except KeyError:
            raise QISKitError("'%s' provider is not registered.")
Example #15
0
    def __init__(self, q_jobs, callback, max_workers=1):
        """
        Args:
            q_jobs (list(QuantumJob)): List of QuantumJob objects.
            callback (fn(results)): The function that will be called when all
                jobs finish. The signature of the function must be:
                fn(results)
                results: A list of Result objects.
            max_workers (int): The maximum number of workers to use.

        Raises:
            QISKitError: if any of the job backends could not be found.
        """
        self.q_jobs = q_jobs
        self.max_workers = max_workers
        # check whether any jobs are remote
        self.online = any(qj.backend not in local_backends() for qj in q_jobs)
        self.futures = {}
        self.lock = Lock()
        # Set a default dummy callback just in case the user doesn't want
        # to pass any callback.
        self.callback = (lambda rs: ()) if callback is None else callback
        self.num_jobs = len(self.q_jobs)
        self.jobs_results = []
        if self.online:
            # verify backends across all jobs
            for q_job in q_jobs:
                if q_job.backend not in remote_backends() + local_backends():
                    raise QISKitError("Backend %s not found!" % q_job.backend)
        if self.online:
            # I/O intensive -> use ThreadedPoolExecutor
            self.executor_class = futures.ThreadPoolExecutor
        else:
            # CPU intensive -> use ProcessPoolExecutor
            self.executor_class = futures.ProcessPoolExecutor
Example #16
0
def least_busy(names):
    """
    Return the least busy available backend for those that
    have a `pending_jobs` in their `status`. Backends such as
    local backends that do not have this are not considered.

    Args:
        names (list[str]): backend names to choose from
                    (e.g. output of ``available_backends()``)

    Returns:
        str: the name of the least busy backend

    Raises:
        QISKitError: if passing a list of backend names that is
            either empty or none have attribute ``pending_jobs``
    """
    backends = [get_backend(name) for name in names]
    try:
        return min([
            b for b in backends
            if b.status()['operational'] and 'pending_jobs' in b.status()
        ],
                   key=lambda b: b.status()['pending_jobs']).name()
    except (ValueError, TypeError):
        raise QISKitError(
            "Can only find least_busy backend from a non-empty list.")
Example #17
0
def register(token, url='https://quantumexperience.ng.bluemix.net/api',
             hub=None, group=None, project=None, proxies=None, verify=True,
             provider_name='ibmq'):
    """
    Authenticate against an online backend provider.

    Args:
            token (str): The token used to register on the online backend such
                as the quantum experience.
            url (str): The url used for online backend such as the quantum
                experience.
            hub (str): The hub used for online backend.
            group (str): The group used for online backend.
            project (str): The project used for online backend.
            proxies (dict): Proxy configuration for the API, as a dict with
                'urls' and credential keys.
            verify (bool): If False, ignores SSL certificates errors.
            provider_name (str): the unique name for the online backend
                provider (for example, 'ibmq' for the IBM Quantum Experience).
    Raises:
        QISKitError: if the provider name is not recognized.
    """
    if provider_name == 'ibmq':
        provider = IBMQProvider(token, url,
                                hub, group, project, proxies, verify)
        _DEFAULT_PROVIDER.add_provider(provider)
    else:
        raise QISKitError('provider name %s is not recognized' % provider_name)
Example #18
0
 def get_output(self):
     """Returns the generated circuit."""
     if not self._is_circuit_valid():
         raise QISKitError(
             "Invalid circuit! Please check the syntax of your circuit."
             "Has the Qasm parsing been called?. e.g: unroller.execute().")
     return self.circuit
Example #19
0
def store_credentials(provider_class=IBMQProvider, overwrite=False,
                      filename=None, **kwargs):
    """
    Store the credentials for a single provider in the configuration file.

    Args:
        provider_class (class): class of the Provider for the credentials.
        overwrite (bool): overwrite existing credentials.
        filename (str): full path to the qiskitrc file. If `None`, the default
            location is used (`HOME/.qiskit/qiskitrc`).
        kwargs (dict): keyword arguments passed to provider class
            initialization.

    Raises:
        QISKitError: If provider already exists and overwrite=False; or if
            the account_name could not be assigned.
    """
    # Set the name of the Provider from the class.
    account_name = get_account_name(provider_class)
    # Read the current providers stored in the configuration file.
    filename = filename or DEFAULT_QISKITRC_FILE
    credentials = read_credentials_from_qiskitrc(filename)
    if account_name in credentials.keys() and not overwrite:
        raise QISKitError('%s is already present and overwrite=False'
                          % account_name)

    # Append the provider, trim the empty options and store it in the file.
    kwargs = {key: value for key, value in kwargs.items() if value is not None}
    credentials[account_name] = {**kwargs}
    write_qiskit_rc(credentials, filename)
Example #20
0
    def add_ibmq_provider(self, credentials_dict, provider_name=None):
        """
        Add a new IBMQProvider to the list of known providers.

        Args:
            credentials_dict (dict): dictionary of credentials for a provider.
            provider_name (str): User-provided name for the provider. A name
                will automatically be assigned if possible.
        Raises:
            QISKitError: if a provider with the same name is already in the
                list; or if a provider name could not be assigned.
        Returns:
            IBMQProvider: the new IBMQProvider instance.
        """
        # Automatically assign a name if not specified.
        if not provider_name:
            if 'quantumexperience' in credentials_dict['url']:
                provider_name = 'ibmq'
            elif 'q-console' in credentials_dict['url']:
                provider_name = 'qnet'
            else:
                raise QISKitError(
                    'Cannot parse provider name from credentials.')

        ibmq_provider = IBMQProvider(**credentials_dict)

        return self.add_provider(ibmq_provider, provider_name)
Example #21
0
def load_qasm_file(qasm_file, name=None,
                   basis_gates="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,"
                               "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap"):
    """Construct a quantum circuit from a qasm representation (file).

    Args:
        qasm_file (str): a string for the filename including its location.
        name (str or None): the name of the quantum circuit after
            loading qasm text into it. If no name is give the name is of
            the text file.
        basis_gates (str): basis gates for the quantum circuit.
    Returns:
         QuantumCircuit: circuit constructed from qasm.
    Raises:
        QISKitError: if the file cannot be read.
    """
    if not os.path.exists(qasm_file):
        raise QISKitError('qasm file "{0}" not found'.format(qasm_file))
    if not name:
        name = os.path.splitext(os.path.basename(qasm_file))[0]

    with open(qasm_file) as file:
        qasm_data = file.read()

    return load_qasm_string(qasm_data, name=name, basis_gates=basis_gates)
    def remove_provider(self, provider):
        """
        Remove a provider from the list of known providers.

        Args:
            provider (BaseProvider): provider to be removed.

        Raises:
            QISKitError: if the provider is not registered.
        """
        if isinstance(provider, LocalProvider):
            raise QISKitError("Cannot unregister 'local' provider.")
        try:
            self.providers.remove(provider)
        except ValueError:
            raise QISKitError("'%s' provider is not registered.")
    def run_circuit(self, circuit):
        """Apply the single-qubit gate.

        Args:
            circuit (QobjExperiment): experiment from qobj experiments list

        Returns:
            dict: A dictionary of results.

        Raises:
            QISKitError: if the number of qubits in the circuit is greater than 24.
            Note that the practical qubit limit is much lower than 24.
        """
        self._number_of_qubits = circuit.header.number_of_qubits
        if self._number_of_qubits > 24:
            raise QISKitError("np.einsum implementation limits local_unitary_simulator" +
                              " to 24 qubit circuits.")
        result = {
            'data': {},
            'name': circuit.header.name
        }

        # Initilize unitary as rank 2*N tensor
        self._unitary_state = np.reshape(np.eye(2 ** self._number_of_qubits,
                                                dtype=complex),
                                         self._number_of_qubits * [2, 2])

        for operation in circuit.instructions:
            if operation.name in ('U', 'u1', 'u2', 'u3'):
                params = getattr(operation, 'params', None)
                qubit = operation.qubits[0]
                gate = single_gate_matrix(operation.name, params)
                self._add_unitary_single(gate, qubit)
            elif operation.name in ('id', 'u0'):
                pass
            elif operation.name in ('CX', 'cx'):
                qubit0 = operation.qubits[0]
                qubit1 = operation.qubits[1]
                gate = np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],
                                 [0, 1, 0, 0]])
                self._add_unitary_two(gate, qubit0, qubit1)
            elif operation.name == 'measure':
                logger.info('Warning have dropped measure from unitary '
                            'simulator')
            elif operation.name == 'reset':
                logger.info('Warning have dropped reset from unitary '
                            'simulator')
            elif operation.name == 'barrier':
                pass
            else:
                result['status'] = 'ERROR'
                return result
        # Reshape unitary rank-2n tensor back to a matrix
        result['data']['unitary'] = np.reshape(self._unitary_state,
                                               2 * [2 ** self._number_of_qubits])
        result['status'] = 'DONE'
        result['success'] = True
        result['shots'] = 1
        return result
Example #24
0
def vqe(molecule='H2', depth=6, max_trials=200, shots=1):
    if molecule == 'H2':
        n_qubits = 2
        Z1 = 1
        Z2 = 1
        min_distance = 0.2
        max_distance = 4

    elif molecule == 'LiH':
        n_qubits = 4
        Z1 = 1
        Z2 = 3
        min_distance = 0.5
        max_distance = 5

    else:
        raise QISKitError("Unknown molecule for VQE.")

    # Read Hamiltonian
    ham_name = os.path.join(os.path.dirname(__file__),
                            molecule + '/' + molecule + 'Equilibrium.txt')
    pauli_list = Hamiltonian_from_file(ham_name)
    H = make_Hamiltonian(pauli_list)

    # Exact Energy
    exact = np.amin(la.eig(H)[0]).real
    print('The exact ground state energy is: {}'.format(exact))

    # Optimization
    device = 'qasm_simulator'
    if shots == 1:
        device = 'statevector_simulator'

    if 'statevector' not in device:
        H = group_paulis(pauli_list)

    entangler_map = get_backend(device).configuration()['coupling_map']

    if entangler_map == 'all-to-all':
        entangler_map = {i: [j for j in range(n_qubits) if j != i] for i in range(n_qubits)}
    else:
        entangler_map = mapper.coupling_list2dict(entangler_map)

    initial_theta = np.random.randn(2 * n_qubits * depth)   # initial angles
    initial_c = 0.01                                        # first theta perturbations
    target_update = 2 * np.pi * 0.1                         # aimed update on first trial
    save_step = 20                                          # print optimization trajectory

    cost = partial(cost_function, H, n_qubits, depth, entangler_map, shots, device)

    SPSA_params, circuits_cal = SPSA_calibration(cost, initial_theta, initial_c,
                                                 target_update, stat=25)
    output, circuits_opt = SPSA_optimization(cost, initial_theta, SPSA_params, max_trials,
                                             save_step, last_avg=1)

    return circuits_cal + circuits_opt
    def available_backends(self, filters=None):
        """Get a list of available backends from all providers (after filtering).

        Note:
            If two or more providers share similar backend names, only the backends
            belonging to the first registered provider will be returned.

        Args:
            filters (dict or callable): filtering conditions.
                each will either pass through, or be filtered out:

                1) dict: {'criteria': value}
                    the criteria can be over backend's `configuration` or `status`
                    e.g. {'local': False, 'simulator': False, 'operational': True}

                2) callable: BaseBackend -> bool
                    e.g. lambda x: x.configuration()['n_qubits'] > 5

        Returns:
            list[BaseBackend]: a list of backend instances available
                from all the providers.

        Raises:
            QISKitError: if passing filters that is neither dict nor callable
        """
        # pylint: disable=arguments-differ
        backends = []
        for provider in self.providers:
            backends.extend(provider.available_backends())

        if filters is not None:
            if isinstance(filters, dict):
                # exact match filter:
                # e.g. {'n_qubits': 5, 'operational': True}
                for key, value in filters.items():
                    backends = [
                        instance for instance in backends
                        if instance.configuration().get(key) == value
                        or instance.status().get(key) == value
                    ]
            elif callable(filters):
                # acceptor filter: accept or reject a specific backend
                # e.g. lambda x: x.configuration()['n_qubits'] > 5
                accepted_backends = []
                for backend in backends:
                    try:
                        if filters(backend) is True:
                            accepted_backends.append(backend)
                    except Exception:  # pylint: disable=broad-except
                        pass
                backends = accepted_backends
            else:
                raise QISKitError(
                    'backend filters must be either dict or callable.')

        return backends
Example #26
0
    def __init__(self,
                 q_jobs,
                 callback,
                 max_workers=1,
                 token=None,
                 url=None,
                 api=None):
        """
        Args:
            q_jobs (list(QuantumJob)): List of QuantumJob objects.
            callback (fn(results)): The function that will be called when all
                jobs finish. The signature of the function must be:
                fn(results)
                results: A list of Result objects.
            max_workers (int): The maximum number of workers to use.
            token (str): Server API token
            url (str): Server URL.
            api (IBMQuantumExperience): API instance to use. If set,
                /token/ and /url/ are ignored.
        """
        self.q_jobs = q_jobs
        self.max_workers = max_workers
        # check whether any jobs are remote
        self._local_backends = backends.local_backends()
        self.online = any(qj.backend not in self._local_backends
                          for qj in q_jobs)
        self.futures = {}
        self.lock = Lock()
        # Set a default dummy callback just in case the user doesn't want
        # to pass any callback.
        self.callback = (lambda rs: ()) if callback is None else callback
        self.num_jobs = len(self.q_jobs)
        self.jobs_results = []
        if self.online:
            self._api = api if api else IBMQuantumExperience(
                token, {"url": url}, verify=True)
            self._online_backends = remote_backends(self._api)
            # Check for the existance of the backend
            for q_job in q_jobs:
                if q_job.backend not in self._online_backends + self._local_backends:
                    raise QISKitError("Backend %s not found!" % q_job.backend)

            self._api_config = {}
            self._api_config["token"] = token
            self._api_config["url"] = {"url": url}
        else:
            self._api = None
            self._online_backends = None
            self._api_config = None
        if self.online:
            # I/O intensive -> use ThreadedPoolExecutor
            self.executor_class = futures.ThreadPoolExecutor
        else:
            # CPU intensive -> use ProcessPoolExecutor
            self.executor_class = futures.ProcessPoolExecutor
Example #27
0
    def _get_experiment(self, key=None):
        """Return an experiment from a given key.

        Args:
            key (str or QuantumCircuit or int or None): the index of the
                experiment, as specified by ``get_data()``.

        Returns:
            ExperimentResult: the results for an experiment.

        Raises:
            QISKitError: if there is no data for the circuit, or an unhandled
                error occurred while fetching the data.
        """
        if not self.success:
            raise QISKitError(
                getattr(self, 'status', 'Result was not successful'))

        # Automatically return the first result if no key was provided.
        if key is None:
            if len(self.results) != 1:
                raise QISKitError(
                    'You have to select a circuit when there is more than '
                    'one available')
            else:
                key = 0

        # Key is an integer: return result by index.
        if isinstance(key, int):
            return self.results[key]

        # Key is a QuantumCircuit or str: retrieve result by name.
        if isinstance(key, QuantumCircuit):
            key = key.name
        try:
            # Look into `result[x].header.name` for the names.
            return next(
                result for result in self.results
                if getattr(getattr(result, 'header', None), 'name', '') == key)
        except StopIteration:
            raise QISKitError('Data for experiment "%s" could not be found.' %
                              key)
Example #28
0
def einsum_matmul_index(gate_indices, number_of_qubits):
    """Return the index string for Numpy.eignsum matrix multiplication.

    The returned indices are to perform a matrix multiplication A.B where
    the matrix A is an M-qubit matrix, matrix B is an N-qubit matrix, and
    M <= N, and identity matrices are implied on the subsystems where A has no
    support on B.

    Args:
        gate_indices (list[int]): the indices of the right matrix subsystems
                                   to contract with the left matrix.
        number_of_qubits (int): the total number of qubits for the right matrix.

    Returns:
        str: An indices string for the Numpy.einsum function.

    Raises:
        QISKitError: if the total number of qubits plus the number of
        contracted indices is greater than 26.
    """

    # Since we use ASCII alphabet for einsum index labels we are limited
    # to 26 total free left (lowercase) and 26 right (uppercase) indexes.
    # The rank of the contracted tensor reduces this as we need to use that
    # many characters for the contracted indices
    if len(gate_indices) + number_of_qubits > 26:
        raise QISKitError("Total number of free indexes limited to 26")

    # Right indices for the N-qubit input and output tensor
    idx_right = ascii_uppercase[:number_of_qubits]

    # Left ndicies for N-qubit input tensor
    idx_left_in = ascii_lowercase[:number_of_qubits]

    # Left indices for the N-qubit output tensor
    idx_left_out = list(idx_left_in)

    # Left and right indices for the M-qubit multiplying tensor
    mat_left = ""
    mat_right = ""

    # Update left indices for mat and output
    for pos, idx in enumerate(reversed(gate_indices)):
        mat_left += ascii_lowercase[-1 - pos]
        mat_right += idx_left_in[-1 - idx]
        idx_left_out[-1 - idx] = ascii_lowercase[-1 - pos]
    idx_left_out = "".join(idx_left_out)

    # Combine indices into matrix multiplication string format
    # for numpy.einsum function
    return "{mat_l}{mat_r}, ".format(mat_l=mat_left, mat_r=mat_right) + \
           "{tens_lin}{tens_r}->{tens_lout}{tens_r}".format(tens_lin=idx_left_in,
                                                            tens_lout=idx_left_out,
                                                            tens_r=idx_right)
Example #29
0
def __pauli_meas_gates(circuit, qreg, op):
    """
    Add state measurement gates to a circuit.
    """
    if op not in ['X', 'Y', 'Z']:
        raise QISKitError("There's no X, Y or Z basis for this Pauli measurement")

    if op == "X":
        circuit.u2(0., np.pi, qreg)  # H
    elif op == "Y":
        circuit.u2(0., 0.5 * np.pi, qreg)  # H.S^*
Example #30
0
    def get_snapshot(self, slot=None, circuit=None):
        """Get snapshot at a specific slot.

        Args:
            slot (str): snapshot slot to retrieve. If None and there is only one
                slot, return that one.
            circuit (str or QuantumCircuit or None): reference to a quantum circuit
                If None and there is only one circuit available, returns
                that one.

        Returns:
            dict[slot: dict[str: array]]: list of 2^n_qubits complex amplitudes.

        Raises:
            QISKitError: if there is no snapshot at all, or in this slot
        """
        try:
            snapshots_dict = self.get_snapshots(circuit)

            if slot is None:
                slots = list(snapshots_dict.keys())
                if len(slots) == 1:
                    slot = slots[0]
                else:
                    raise QISKitError("You have to select a slot when there "
                                      "is more than one available")
            snapshot_dict = snapshots_dict[slot]

            snapshot_types = list(snapshot_dict.keys())
            if len(snapshot_types) == 1:
                snapshot_list = snapshot_dict[snapshot_types[0]]
                if len(snapshot_list) == 1:
                    return snapshot_list[0]
                else:
                    return snapshot_list
            else:
                return snapshot_dict
        except KeyError:
            raise QISKitError('No snapshot at slot {0} for '
                              'circuit "{1}"'.format(slot, circuit))