コード例 #1
0
ファイル: noise.py プロジェクト: shukob/tequila
    def __init__(self, name: str, probs: typing.List[float], level: int):
        """

        Parameters
        ----------
        name: str
            what the name of the noise is. Determines how many probabilites are needed additionally.
        probs: list:
            a list of probabilities with which to apply the requested noise
        level: int:
            the number of qubits in the gates this noise acts upon.
        """
        probs = list_assignement(probs)
        if name not in noises_available:
            raise TequilaException(
                'The name you asked for, {}, is not recognized'.format(name))
        self._name = name
        self._level = int(level)

        if len(probs) != self.prob_length[name]:
            raise TequilaException(
                '{} noise requires {} probabilities; recieved {}'.format(
                    name, self.prob_length[name], len(probs)))
        if name in krausses:
            assert sum(probs) <= 1.
        self.probs = list_assignement(probs)
コード例 #2
0
    def __init__(self, name: str, probs: typing.List[float], level: int):
        probs = list_assignement(probs)
        if name not in noises_available:
            raise TequilaException(
                'The name you asked for, {}, is not recognized'.format(name))
        self._name = name
        self._level = int(level)

        if len(probs) != self.prob_length[name]:
            raise TequilaException(
                '{} noise requires {} probabilities; recieved {}'.format(
                    name, self.prob_length[name], len(probs)))
        if name in krausses:
            assert sum(probs) <= 1.
        self.probs = list_assignement(probs)
コード例 #3
0
    def simulate(self, variables, initial_state=0, *args, **kwargs) -> QubitWaveFunction:
        """
        Simulate the wavefunction
        :param returntype: specifies how the result should be given back
        :param initial_state: The initial state of the simulation,
        if given as an integer this is interpreted as the corresponding multi-qubit basis state
        :return: The resulting state
        """
        self.update_variables(variables)
        if isinstance(initial_state, BitString):
            initial_state = initial_state.integer
        if isinstance(initial_state, QubitWaveFunction):
            if len(initial_state.keys()) != 1:
                raise TequilaException("only product states as initial states accepted")
            initial_state = list(initial_state.keys())[0].integer

        all_qubits = [i for i in range(self.abstract_circuit.n_qubits)]
        if self.use_mapping:
            active_qubits = self.abstract_circuit.qubits
            # maps from reduced register to full register
            keymap = KeyMapSubregisterToRegister(subregister=active_qubits, register=all_qubits)
        else:
            keymap = KeyMapSubregisterToRegister(subregister=all_qubits, register=all_qubits)

        result = self.do_simulate(variables=variables, initial_state=keymap.inverted(initial_state).integer, *args, **kwargs)
        result.apply_keymap(keymap=keymap, initial_state=initial_state)
        return result
コード例 #4
0
 def from_dict(d):
     if isinstance(d, dict):
         return Noise(**d)
     elif isinstance(d, Noise):
         return d
     else:
         raise TequilaException('who the f**k do you think you are?')
コード例 #5
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def sample_all_z_hamiltonian(self, samples: int, hamiltonian, variables,
                                 *args, **kwargs):
        """
        Sample from a Hamiltonian which only consists of Pauli-Z and unit operators
        Parameters
        ----------
        samples
            number of samples to take
        hamiltonian
            the tequila hamiltonian
        args
            arguments for do_sample
        kwargs
            keyword arguments for do_sample
        Returns
        -------
            samples, evaluated and summed Hamiltonian expectationvalue
        """
        # make measurement instruction (measure all qubits in the Hamiltonian that are also in the circuit)
        abstract_qubits_H = hamiltonian.qubits
        assert len(
            abstract_qubits_H) != 0  # this case should be filtered out before
        # assert that the Hamiltonian was mapped before
        if not all(q in self.qubit_map.keys() for q in abstract_qubits_H):
            raise TequilaException(
                "Qubits in {}-qubit Hamiltonian were not traced out for {}-qubit circuit"
                .format(hamiltonian.n_qubits, self.n_qubits))

        # run simulators
        counts = self.sample(samples=samples,
                             read_out_qubits=abstract_qubits_H,
                             variables=variables,
                             *args,
                             **kwargs)
        read_out_map = {q: i for i, q in enumerate(abstract_qubits_H)}

        # compute energy
        E = 0.0
        for paulistring in hamiltonian.paulistrings:
            n_samples = 0
            Etmp = 0.0
            for key, count in counts.items():
                # get all the non-trivial qubits of the current PauliString (meaning all Z operators)
                # and mapp them to the backend qubits
                mapped_ps_support = [
                    read_out_map[i] for i in paulistring._data.keys()
                ]
                # count all measurements that resulted in |1> for those qubits
                parity = [
                    k for i, k in enumerate(key.array)
                    if i in mapped_ps_support
                ].count(1)
                # evaluate the PauliString
                sign = (-1)**parity
                Etmp += sign * count
                n_samples += count
            E += (Etmp / samples) * paulistring.coeff
            # small failsafe
            assert n_samples == samples
        return E
コード例 #6
0
ファイル: simulator_base.py プロジェクト: akpc/margarita
    def simulate(self, variables, *args, **kwargs):
        self.update_variables(variables)
        result = []
        for H in self.H:
            final_E = 0.0
            if self.use_mapping:
                # The hamiltonian can be defined on more qubits as the unitaries
                qubits_h = H.qubits
                qubits_u = self.U.qubits
                all_qubits = list(
                    set(qubits_h) | set(qubits_u)
                    | set(range(self.U.abstract_circuit.max_qubit() + 1)))
                keymap = KeyMapSubregisterToRegister(subregister=qubits_u,
                                                     register=all_qubits)
            else:
                if H.qubits != self.U.qubits:
                    raise TequilaException(
                        "Can not compute expectation value without using qubit mappings."
                        " Your Hamiltonian and your Unitary do not act on the same set of qubits. "
                        "Hamiltonian acts on {}, Unitary acts on {}".format(
                            H.qubits, self.U.qubits))
                keymap = KeyMapSubregisterToRegister(subregister=self.U.qubits,
                                                     register=self.U.qubits)
            # TODO inefficient, let the backend do it if possible or interface some library
            simresult = self.U.simulate(variables=variables, *args, **kwargs)
            wfn = simresult.apply_keymap(keymap=keymap)
            final_E += wfn.compute_expectationvalue(operator=H)

            result.append(to_float(final_E))
        return numpy.asarray(result)
コード例 #7
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def do_sample(self,
                  samples,
                  circuit,
                  noise,
                  abstract_qubits=None,
                  *args,
                  **kwargs) -> QubitWaveFunction:
        """
        helper function for sampling. MUST be overwritten by inheritors.

        Parameters
        ----------
        samples: int:
            the number of samples to take
        circuit:
            the circuit to sample from.
            Note:
            Not necessarily self.circuit!
        noise:
            the noise to apply to the sampled circuit.
        abstract_qubits:
            specify which qubits to measure. Default is all
        args
        kwargs

        Returns
        -------
        QubitWaveFunction:
            the result of sampling.

        """
        TequilaException(
            "Backend Handler needs to be overwritten for supported simulators")
コード例 #8
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def __call__(self, variables, samples: int = None, *args, **kwargs):

        variables = format_variable_dictionary(variables=variables)
        if self._variables is not None and len(self._variables) > 0:
            if variables is None or (
                    not set(self._variables) <= set(variables.keys())):
                raise TequilaException(
                    "BackendExpectationValue received not all variables. Circuit depends on variables {}, you gave {}"
                    .format(self._variables, variables))

        if samples is None:
            data = self.simulate(variables=variables, *args, **kwargs)
        else:
            data = self.sample(variables=variables,
                               samples=samples,
                               *args,
                               **kwargs)

        if self._shape is None and self._contraction is None:
            # this is the default
            return numpy.sum(data)

        if self._shape is not None:
            data = data.reshape(self._shape)
        if self._contraction is None:
            return data
        else:
            return self._contraction(data)
コード例 #9
0
ファイル: noise.py プロジェクト: shukob/tequila
 def from_dict(d):
     if type(d) is dict:
         return QuantumNoise(**d)
     elif type(d) is QuantumNoise:
         return d
     else:
         raise TequilaException(
             'object provided is neither a dictionary nor a QuantumNoise.')
コード例 #10
0
 def __call__(self,
              variables: typing.Dict[Variable, numbers.Real] = None,
              samples: int = None,
              *args,
              **kwargs):
     variables = format_variable_dictionary(variables=variables)
     if self._variables is not None and len(self._variables) > 0:
         if variables is None or set(self._variables) != set(variables.keys()):
             raise TequilaException("BackendCircuit received not all variables. Circuit depends on variables {}, you gave {}".format(self._variables, variables))
     if samples is None:
         return self.simulate(variables=variables, noise_model=self.noise_model, *args, **kwargs)
     else:
         return self.sample(variables=variables, samples=samples, noise_model=self.noise_model, *args, **kwargs)
コード例 #11
0
ファイル: simulator_base.py プロジェクト: shukob/tequila
    def simulate(self,
                 variables,
                 initial_state=0,
                 *args,
                 **kwargs) -> QubitWaveFunction:
        """
        simulate the circuit via the backend.

        Parameters
        ----------
        variables:
            the parameters with which to simulate the circuit.
        initial_state: Default = 0:
            one of several types; determines the base state onto which the circuit is applied.
            Default: the circuit is applied to the all-zero state.
        args
        kwargs

        Returns
        -------
        QubitWaveFunction:
            the wavefunction of the system produced by the action of the circuit on the initial state.

        """
        self.update_variables(variables)
        if isinstance(initial_state, BitString):
            initial_state = initial_state.integer
        if isinstance(initial_state, QubitWaveFunction):
            if len(initial_state.keys()) != 1:
                raise TequilaException(
                    "only product states as initial states accepted")
            initial_state = list(initial_state.keys())[0].integer

        all_qubits = [i for i in range(self.abstract_circuit.n_qubits)]
        if self.use_mapping:
            active_qubits = self.abstract_circuit.qubits
            # maps from reduced register to full register
            keymap = KeyMapSubregisterToRegister(subregister=active_qubits,
                                                 register=all_qubits)
        else:
            keymap = KeyMapSubregisterToRegister(subregister=all_qubits,
                                                 register=all_qubits)

        result = self.do_simulate(
            variables=variables,
            initial_state=keymap.inverted(initial_state).integer,
            *args,
            **kwargs)
        result.apply_keymap(keymap=keymap, initial_state=initial_state)
        return result
コード例 #12
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def check_device(self, device):
        """
        Verify if a device can be used in the selected backend. Overwritten by inheritors.
        Parameters
        ----------
        device:
            the device to verify.

        Returns
        -------

        Raises
        ------
        TequilaException
        """
        if device is not None:
            TequilaException('Devices not enabled for {}'.format(
                str(type(self))))
コード例 #13
0
ファイル: optimizer_gd.py プロジェクト: philipp-q/tequila-1
    def step(self, objective: Objective, parameters: typing.Dict[Variable, numbers.Real]) -> \
            typing.Dict[Variable, numbers.Real]:
        """
        perform a single optimization step and return suggested parameters.
        Parameters
        ----------
        objective: Objective:
            the compiled objective, to perform an optimization step for. MUST be one returned by prepare.
        parameters: dict:
            the parameters to use in performing the optimization step.

        Returns
        -------
        dict
            dict of new suggested parameters.
        """
        s = id(objective)
        try:
            gradients = self.gradient_lookup[s]
            active_keys = self.active_key_lookup[s]
            last_moment = self.moments_lookup[s]
            adam_step = self.step_lookup[s]
        except:
            raise TequilaException(
                'Could not retrieve necessary information. Please use the prepare function before optimizing!'
            )
        new, moments, grads = self.f(step=adam_step,
                                     gradients=gradients,
                                     active_keys=active_keys,
                                     moments=last_moment,
                                     v=parameters)
        back = {**parameters}
        for k in new.keys():
            back[k] = new[k]
        save_grad = {}
        self.moments_lookup[s] = moments
        self.moments_trajectory[s].append(moments)
        if self.save_history:
            for i, k in enumerate(active_keys):
                save_grad[k] = grads[i]
            self.history.gradients.append(save_grad)
        self.step_lookup[s] += 1
        self.__dx = grads  # most recent gradient
        return back
コード例 #14
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def __call__(self,
                 variables: typing.Dict[Variable, numbers.Real] = None,
                 samples: int = None,
                 *args,
                 **kwargs):
        """
        Simulate or sample the backend circuit.

        Parameters
        ----------
        variables: dict:
            dictionary assigning values to the variables of the circuit.
        samples: int, optional:
            how many shots to sample with. If None, perform full wavefunction simulation.
        args
        kwargs

        Returns
        -------
        Float:
            the result of simulating or sampling the circuit.
        """

        variables = format_variable_dictionary(variables=variables)
        if self._variables is not None and len(self._variables) > 0:
            if variables is None or set(self._variables) != set(
                    variables.keys()):
                raise TequilaException(
                    "BackendCircuit received not all variables. Circuit depends on variables {}, you gave {}"
                    .format(self._variables, variables))
        if samples is None:
            return self.simulate(variables=variables,
                                 noise=self.noise,
                                 *args,
                                 **kwargs)
        else:
            return self.sample(variables=variables,
                               samples=samples,
                               noise=self.noise,
                               *args,
                               **kwargs)
コード例 #15
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def retrieve_device(self, device):
        """
        get the instantiated backend device object, from user provided object (e.g, a string).

        Must be overwritten by inheritors, to use devices.

        Parameters
        ----------
        device:
            object which points to the device in question, to be returned.

        Returns
        -------
        Type:
            varies by backend.
        """
        if device is None:
            return device
        else:
            TequilaException('Devices not enabled for {}'.format(
                str(type(self))))
コード例 #16
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
    def do_simulate(self, variables, initial_state, *args,
                    **kwargs) -> QubitWaveFunction:
        """
        helper for simulation. MUST be overwritten by inheritors.

        Parameters
        ----------
        variables:
            the variables with which the circuit may be simulated.
        initial_state:
            the initial state in which the system is in prior to the application of the circuit.
        args
        kwargs

        Returns
        -------
        QubitWaveFunction
            the result of simulating the circuit.

        """
        TequilaException(
            "Backend Handler needs to be overwritten for supported simulators")
コード例 #17
0
ファイル: optimizer_gd.py プロジェクト: stjordanis/tequila
 def step(self, objective, parameters):
     s = id(objective)
     try:
         gradients = self.gradient_lookup[s]
         active_keys = self.active_key_lookup[s]
         last_moment = self.moments_lookup[s]
         adam_step = self.step_lookup[s]
     except:
         raise TequilaException(
             'Could not retrieve necessary information. Please use the prepare function before optimizing!')
     new, moments, grads = self.f(step=adam_step, gradients=gradients, active_keys=active_keys, moments=last_moment,
                                  v=parameters)
     back = {**parameters}
     for k in new.keys():
         back[k] = new[k]
     save_grad = {}
     self.moments_lookup[s] = moments
     self.moments_trajectory[s].append(moments)
     if self.save_history:
         for i, k in enumerate(active_keys):
             save_grad[k] = grads[i]
         self.history.gradients.append(save_grad)
     self.step_lookup[s] += 1
     return back
コード例 #18
0
ファイル: simulator_base.py プロジェクト: akpc/margarita
 def do_sample(self, samples, circuit, noise, *args,
               **kwargs) -> QubitWaveFunction:
     TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #19
0
ファイル: simulator_base.py プロジェクト: akpc/margarita
 def do_simulate(self, variables, initial_state, *args,
                 **kwargs) -> QubitWaveFunction:
     TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #20
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
 def convert_measurements(self, backend_result) -> QubitWaveFunction:
     TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #21
0
ファイル: simulator_base.py プロジェクト: d4rkc0nd0r/tequila
 def add_parametrized_gate(self, gate, circuit, *args, **kwargs):
     raise TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #22
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
 def initialize_circuit(self, *args, **kwargs):
     TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #23
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
 def add_measurement(self, circuit, target_qubits, *args, **kwargs):
     TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #24
0
ファイル: simulator_base.py プロジェクト: gmgalvan/tequila
 def add_basic_gate(self, gate, circuit, *args, **kwargs):
     TequilaException(
         "Backend Handler needs to be overwritten for supported simulators")
コード例 #25
0
ファイル: simulator_base.py プロジェクト: philipp-q/tequila-1
    def __init__(self,
                 abstract_circuit: QCircuit,
                 variables,
                 noise=None,
                 device=None,
                 qubit_map=None,
                 optimize_circuit=True,
                 *args,
                 **kwargs):
        """

        Parameters
        ----------
        abstract_circuit: QCircuit:
            the circuit which is to be rendered in the backend language.
        variables:
            values for the variables of abstract_circuit
        noise: optional:
            noise to apply to abstract circuit.
        device: optional:
            device on which to sample (or emulate sampling) abstract circuit.
        qubit_map: dictionary:
            a qubit map which maps the abstract qubits in the abstract_circuit to the qubits on the backend
            there is no need to initialize the corresponding backend types
            the dictionary should simply be {int:int} (preferred) or {int:name}
            if None the default will map to qubits 0 ... n_qubits -1 in the backend
        optimize_circuit: bool:
            whether or not to attempt backend depth optimization. Defaults to true.
        args
        kwargs
        """

        self._input_args = {
            "abstract_circuit": abstract_circuit,
            "variables": variables,
            "noise": noise,
            "qubit_map": qubit_map,
            "optimize_circuits": optimize_circuit,
            "device": device,
            **kwargs
        }

        self.no_translation = False
        self._variables = tuple(abstract_circuit.extract_variables())

        compiler_arguments = self.compiler_arguments
        if noise is not None:
            compiler_arguments["cc_max"] = True
            compiler_arguments["controlled_phase"] = True
            compiler_arguments["controlled_rotation"] = True
            compiler_arguments["hadamard_power"] = True

        # compile the abstract_circuit
        c = compiler.Compiler(**compiler_arguments)

        if qubit_map is None:
            qubit_map = {q: i for i, q in enumerate(abstract_circuit.qubits)}
        elif not qubit_map == {
                q: i
                for i, q in enumerate(abstract_circuit.qubits)
        }:
            warnings.warn(
                "reveived custom qubit_map = {}\n"
                "This is not fully integrated and might result in unexpected behaviour!"
                .format(qubit_map), TequilaWarning)

            if len(qubit_map) > abstract_circuit.max_qubit() + 1:
                raise TequilaException(
                    "Custom qubit_map has too many qubits {} vs {}".format(
                        len(qubit_map),
                        abstract_circuit.max_qubit() + 1))
            if max(qubit_map.keys()) > abstract_circuit.max_qubit():
                raise TequilaException(
                    "Custom qubit_map tries to assign qubit {} but we only have {}"
                    .format(max(qubit_map.keys()),
                            abstract_circuit.max_qubit()))

        # qubit map is initialized to have BackendQubits as values (they carry number and instance attributes)
        self.qubit_map = self.make_qubit_map(qubit_map)

        # pre-compilation (still an abstract ciruit, but with gates decomposed depending on backend requirements)
        compiled = c(abstract_circuit)
        self.abstract_circuit = compiled

        self.noise = noise
        self.check_device(device)
        self.device = self.retrieve_device(device)

        # translate into the backend object
        self.circuit = self.create_circuit(abstract_circuit=compiled,
                                           variables=variables)

        if optimize_circuit and noise is None:
            self.circuit = self.optimize_circuit(circuit=self.circuit)