Exemplo n.º 1
0
 def run_sweep(
         self,
         program: 'cirq.Circuit',
         params: 'cirq.Sweepable',
         repetitions: int = 1,
 ) -> List['cirq.Result']:
     assert isinstance(program, circuits.Circuit)
     meas = list(program.findall_operations_with_gate_type(
         ops.MeasurementGate))
     if len(meas) == 0:
         raise ValueError()
     elif len(meas) > 1:
         for _, m, _ in meas:
             assert len(m.qubits) == 1
         results = [
             study.Result(
                 params=p,
                 measurements={gate.key: np.zeros(
                     (repetitions, 1), dtype=int)
                     for _, _, gate in meas})
             for p in study.to_resolvers(params)
         ]
     else:
         assert len(meas) == 1
         i, op, gate = meas[0]
         n_qubits = len(op.qubits)
         k = gate.key
         results = [
             study.Result(
                 params=p,
                 measurements={k: np.zeros(
                     (repetitions, n_qubits), dtype=int)})
             for p in study.to_resolvers(params)
         ]
     return results
Exemplo n.º 2
0
    def run_sweep(
        self,
        program: 'cirq.AbstractCircuit',
        params: study.Sweepable,
        repetitions: int = 1,
    ) -> List[study.Result]:
        """Samples circuit as if every measurement resulted in zero.

        Args:
            program: The circuit to sample from.
            params: Parameters to run with the program.
            repetitions: The number of times to sample.

        Returns:
            Result list for this run; one for each possible parameter
            resolver.

        Raises:
            ValueError if this sampler has a device and the circuit is not
            valid for the device.
        """
        if self.device:
            self.device.validate_circuit(program)
        measurements = {}  # type: Dict[str, np.ndarray]
        for op in program.all_operations():
            key = protocols.measurement_key_name(op, default=None)
            if key is not None:
                measurements[key] = np.zeros((repetitions, len(op.qubits)),
                                             dtype=int)
        return [
            study.Result(params=param_resolver, measurements=measurements)
            for param_resolver in study.to_resolvers(params)
        ]
Exemplo n.º 3
0
    def to_cirq_result(
        self,
        params: Optional[study.ParamResolver] = None,
    ) -> study.Result:
        """Returns a `cirq.Result` for these results.

        `cirq.Result` contains a less dense representation of results than that returned by
        the IonQ API.  Typically these results are also ordered by when they were run, though
        that contract is implicit.  Because the IonQ API does not retain that ordering information,
        the order of these `cirq.Result` objects should *not* be interpetted as representing the
        order in which the circuit was repeated.

        Args:
            params: The `cirq.ParamResolver` used to generate these results.

        Returns:
            The `cirq.Result` for these results.

        Raises:
            ValueError: If the circuit used to produce this result had no measurement gates
                (and hence no measurement keys).
        """
        if len(self.measurement_dict()) == 0:
            raise ValueError(
                'Can convert to cirq results only if the circuit had measurement gates '
                'with measurement keys.')
        measurements = {}
        for key, targets in self.measurement_dict().items():
            qpu_results = list(self.counts(key).elements())
            measurements[key] = np.array(
                list(
                    digits.big_endian_int_to_bits(x, bit_count=len(targets))
                    for x in qpu_results))
        return study.Result(params=params or study.ParamResolver({}),
                            measurements=measurements)
Exemplo n.º 4
0
    def to_cirq_result(
        self,
        params: study.ParamResolver = None,
        seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
        override_repetitions=None,
    ) -> study.Result:
        """Samples from the simulation probability result, producing a `cirq.Result`.

        The IonQ simulator returns the probabilities of different bitstrings. This converts such
        a representation to a randomly generated sample from the simulator. Note that it does this
        on every subsequent call of this method, so repeated calls do not produce the same
        `cirq.Result`s. When a job was created by the IonQ API, it had a number of repetitions and
        this is used, unless `override_repetitions` is set here.

        Args:
            params: Any parameters which were used to generated this result.
            seed: What to use for generating the randomness. If None, then `np.random` is used.
                If an integer, `np.random.RandomState(seed) is used. Otherwise if another
                randomness generator is used, it will be used.
            override_repetitions: Repetitions were supplied when the IonQ API ran the simulation,
                but different repetitions can be supplied here and will override.

        Returns:
            A `cirq.Result` corresponding to a sample from the probability distribution returned
            from the simulator.

        Raises:
            ValueError: If the circuit used to produce this result had no measurement gates
                (and hence no measurement keys).
        """
        if len(self.measurement_dict()) == 0:
            raise ValueError(
                'Can convert to cirq results only if the circuit had measurement gates '
                'with measurement keys.')
        rand = value.parse_random_state(seed)
        measurements = {}
        values, weights = zip(*list(self.probabilities().items()))
        indices = rand.choice(range(len(values)),
                              p=weights,
                              size=override_repetitions or self.repetitions())
        rand_values = np.array(values)[indices]
        for key, targets in self.measurement_dict().items():
            bits = [[(value >> (self.num_qubits() - target - 1)) & 1
                     for target in targets] for value in rand_values]
            measurements[key] = bits
        return study.Result(params=params or study.ParamResolver({}),
                            measurements=measurements)
Exemplo n.º 5
0
    def run_sweep_iter(
        self,
        program: 'cirq.AbstractCircuit',
        params: 'cirq.Sweepable',
        repetitions: int = 1,
    ) -> Iterator['cirq.Result']:
        """Runs the supplied Circuit, mimicking quantum hardware.

        In contrast to run, this allows for sweeping over different parameter
        values.

        Args:
            program: The circuit to simulate.
            params: Parameters to run with the program.
            repetitions: The number of repetitions to simulate.

        Returns:
            Result list for this run; one for each possible parameter
            resolver.

        Raises:
            ValueError: If the circuit has no measurements.
        """
        if not program.has_measurements():
            raise ValueError("Circuit has no measurements to sample.")

        _verify_unique_measurement_keys(program)

        for param_resolver in study.to_resolvers(params):
            measurements = {}
            if repetitions == 0:
                for _, op, _ in program.findall_operations_with_gate_type(
                        ops.MeasurementGate):
                    measurements[protocols.measurement_key_name(
                        op)] = np.empty([0, 1])
            else:
                measurements = self._run(circuit=program,
                                         param_resolver=param_resolver,
                                         repetitions=repetitions)
            yield study.Result(params=param_resolver,
                               measurements=measurements)
Exemplo n.º 6
0
    def run_sweep(self,
                  program: 'cirq.Circuit',
                  params: study.Sweepable,
                  repetitions: int = 1) -> List[study.Result]:
        """Samples from the given Circuit.

        In contrast to run, this allows for sweeping over different parameter
        values.

        Args:
            program: The circuit to simulate.
            Should be generated using AQTSampler.generate_circuit_from_list
            params: Parameters to run with the program.
            repetitions: The number of repetitions to simulate.

        Returns:
            Result list for this run; one for each possible parameter
            resolver.
        """
        # TODO: Use measurement name from circuit.
        # Github issue: https://github.com/quantumlib/Cirq/issues/2199
        meas_name = 'm'
        assert isinstance(program.device, IonDevice)
        trial_results = []  # type: List[study.Result]
        for param_resolver in study.to_resolvers(params):
            id_str = uuid.uuid1()
            num_qubits = len(program.device.qubits)
            json_str = self._generate_json(circuit=program,
                                           param_resolver=param_resolver)
            results = self._send_json(json_str=json_str,
                                      id_str=id_str,
                                      repetitions=repetitions,
                                      num_qubits=num_qubits)
            results = results.astype(bool)
            res_dict = {meas_name: results}
            trial_results.append(
                study.Result(params=param_resolver, measurements=res_dict))
        return trial_results