示例#1
0
    def do_sample(self,
                  samples,
                  circuit,
                  noise_model=None,
                  initial_state=0,
                  *args,
                  **kwargs) -> QubitWaveFunction:
        assert (noise_model is None)
        state = qulacs.QuantumState(self.n_qubits)
        lsb = BitStringLSB.from_int(initial_state, nbits=self.n_qubits)
        state.set_computational_basis(
            BitString.from_binary(lsb.binary).integer)
        self.circuit.update_quantum_state(state)
        if hasattr(self, "measurements"):
            result = {}
            for sample in range(samples):
                sample_result = {}
                for t, m in self.measurements.items():
                    m.update_quantum_state(state)
                    sample_result[t] = state.get_classical_value(t)

                sample_result = dict(
                    sorted(sample_result.items(), key=lambda x: x[0]))
                binary = BitString.from_array(sample_result.values())
                if binary in result:
                    result[binary] += 1
                else:
                    result[binary] = 1

            return QubitWaveFunction(state=result)
        else:
            # sample from the whole wavefunction (all-Z measurement)
            result = state.sampling(samples)
        return self.convert_measurements(backend_result=result)
示例#2
0
 def convert_bitstring(key: typing.Union[BitString, numbers.Integral], n_qubits):
     if isinstance(key, numbers.Integral):
         return BitString.from_int(integer=key, nbits=n_qubits)
     elif isinstance(key, str):
         return BitString.from_binary(binary=key, nbits=n_qubits)
     else:
         return key
示例#3
0
    def do_sample(self,
                  samples,
                  circuit,
                  noise_model=None,
                  initial_state=0,
                  *args,
                  **kwargs) -> QubitWaveFunction:
        """
        Helper function for performing sampling.

        Parameters
        ----------
        samples: int:
            the number of samples to be taken.
        circuit:
            the circuit to sample from.
        noise_model: optional:
            noise model to be applied to the circuit.
        initial_state:
            sampling supports initial states for qulacs. Indicates the initial state to which circuit is applied.
        args
        kwargs

        Returns
        -------
        QubitWaveFunction:
            the results of sampling, as a Qubit Wave Function.
        """
        state = self.initialize_state(self.n_qubits)
        lsb = BitStringLSB.from_int(initial_state, nbits=self.n_qubits)
        state.set_computational_basis(
            BitString.from_binary(lsb.binary).integer)
        circuit.update_quantum_state(state)
        sampled = state.sampling(samples)
        return self.convert_measurements(backend_result=sampled)
示例#4
0
    def convert_measurements(self, backend_result) -> QubitWaveFunction:
        """
        Transform backend evaluation results into QubitWaveFunction
        Parameters
        ----------
        backend_result:
            the return value of backend simulation.

        Returns
        -------
        QubitWaveFunction
            results transformed to tequila native QubitWaveFunction
        """
        result = QubitWaveFunction()
        # todo there are faster ways

        for k in backend_result:
            converted_key = BitString.from_binary(
                BitStringLSB.from_int(integer=k, nbits=self.n_qubits).binary)
            if converted_key in result._state:
                result._state[converted_key] += 1
            else:
                result._state[converted_key] = 1

        if hasattr(self, "measurements"):
            mqubits = self.measurements
            keymap = KeyMapRegisterToSubregister(
                subregister=mqubits,
                register=[i for i in range(self.n_qubits)])
            result = result.apply_keymap(keymap=keymap)

        return result
示例#5
0
    def do_simulate(self, variables, initial_state, *args, **kwargs):
        """
        Helper function to perform simulation.

        Parameters
        ----------
        variables: dict:
            variables to supply to the circuit.
        initial_state:
            information indicating the initial state on which the circuit should act.
        args
        kwargs

        Returns
        -------
        QubitWaveFunction:
            QubitWaveFunction representing result of the simulation.
        """
        state = self.initialize_state(n_qubits=self.n_qubits)
        lsb = BitStringLSB.from_int(initial_state, nbits=self.n_qubits)
        state.set_computational_basis(
            BitString.from_binary(lsb.binary).integer)
        self.circuit.update_quantum_state(state)

        wfn = QubitWaveFunction.from_array(arr=state.get_vector(),
                                           numbering=self.numbering)
        return wfn
示例#6
0
 def from_int(cls, i: int, coeff=1, n_qubits: int = None):
     if isinstance(i, BitString):
         return QubitWaveFunction(state={i: coeff}, n_qubits=n_qubits)
     else:
         return QubitWaveFunction(
             state={BitString.from_int(integer=i, nbits=n_qubits): coeff},
             n_qubits=n_qubits)
示例#7
0
    def do_simulate(self, variables, initial_state, *args, **kwargs):
        state = qulacs.QuantumState(self.n_qubits)
        lsb = BitStringLSB.from_int(initial_state, nbits=self.n_qubits)
        state.set_computational_basis(BitString.from_binary(lsb.binary).integer)
        self.circuit.update_quantum_state(state)

        wfn = QubitWaveFunction.from_array(arr=state.get_vector(), numbering=self.numbering)
        return wfn
示例#8
0
 def convert_measurements(self, backend_result) -> QubitWaveFunction:
     result = QubitWaveFunction()
     # todo there are faster ways
     for k in backend_result:
         converted_key = BitString.from_binary(BitStringLSB.from_int(integer=k, nbits=self.n_qubits).binary)
         if converted_key in result._state:
             result._state[converted_key] += 1
         else:
             result._state[converted_key] = 1
     return result
示例#9
0
 def apply_paulistring(self, paulistring: 'PauliString'):
     """
     Inefficient function which computes action of a single paulistring
     :param paulistring: PauliString
     :return: Expectation Value
     """
     result = QubitWaveFunction()
     for k, v in self.items():
         arr = k.array
         c = v
         for idx, p in paulistring.items():
             if p.lower() == "x":
                 arr[idx] = (arr[idx] + 1) % 2
             elif p.lower() == "y":
                 c *= 1.0j * (-1) ** (arr[idx])
                 arr[idx] = (arr[idx] + 1) % 2
             elif p.lower() == "z":
                 c *= (-1) ** (arr[idx])
             else:
                 raise TequilaException("unknown pauli: " + str(p))
         result[BitString.from_array(array=arr)] = c
     return paulistring.coeff * result
示例#10
0
    def from_string(cls, string: str, n_qubits: int = None):
        """
        Complex values like (x+iy)|...> will currently not work, you need to type Real and imaginary separately
        Or improve this constructor :-)
        e.g instead of (0.5+1.0j)|0101> do 0.5|0101> + 1.0j|0101>
        :param paths:
        :param string:
        :return:
        """
        try:
            state = dict()
            string = string.replace(" ", "")
            string = string.replace("*", "")
            string = string.replace("+-", "-")
            string = string.replace("-+", "-")
            terms = (string + "terminate").split('>')
            for term in terms:
                if term == 'terminate':
                    break
                tmp = term.split("|")
                coeff = tmp[0]
                if coeff == '':
                    coeff = 1.0
                else:
                    coeff = complex(coeff)
                basis_state = BitString.from_binary(binary=tmp[1])

                state[basis_state] = coeff
        except ValueError:
            raise TequilaException(
                "Failed to initialize QubitWaveFunction from string:" +
                string + "\n"
                "did you try complex values?\n"
                "currently you need to type real and imaginary parts separately\n"
                "e.g. instead of (0.5+1.0j)|0101> do 0.5|0101> + 1.0j|0101>")
        except:
            raise TequilaException(
                "Failed to initialize QubitWaveFunction from string:" + string)
        return QubitWaveFunction(state=state, n_qubits=n_qubits)
示例#11
0
    def convert_measurements(self,
                             backend_result,
                             target_qubits=None) -> QubitWaveFunction:
        """
        Transform backend evaluation results into QubitWaveFunction
        Parameters
        ----------
        backend_result:
            the return value of backend simulation.

        Returns
        -------
        QubitWaveFunction
            results transformed to tequila native QubitWaveFunction
        """

        result = QubitWaveFunction()
        # todo there are faster ways

        for k in backend_result:
            converted_key = BitString.from_binary(
                BitStringLSB.from_int(integer=k, nbits=self.n_qubits).binary)
            if converted_key in result._state:
                result._state[converted_key] += 1
            else:
                result._state[converted_key] = 1

        if target_qubits is not None:
            mapped_target = [self.qubit_map[q].number for q in target_qubits]
            mapped_full = [
                self.qubit_map[q].number for q in self.abstract_qubits
            ]
            keymap = KeyMapRegisterToSubregister(subregister=mapped_target,
                                                 register=mapped_full)
            result = result.apply_keymap(keymap=keymap)

        return result