Ejemplo n.º 1
0
    def flatten(self, val: Any) -> Any:
        """Returns a copy of `val` with any symbols or expressions replaced with
        new symbols.  `val` can be a `Circuit`, `Gate`, `Operation`, or other
        type.

        This method mutates the `_ParamFlattener` by storing any new mappings
        from expression to symbol that is uses on val.

        Args:
            val: The value to copy with substituted parameters.
        """
        return protocols.resolve_parameters(val, self)
Ejemplo n.º 2
0
    def _run(self, circuit: circuits.Circuit,
             param_resolver: study.ParamResolver,
             repetitions: int) -> Dict[str, np.ndarray]:
        """See definition in `cirq.SimulatesSamples`."""
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        self._check_all_resolved(resolved_circuit)

        if circuit.are_all_measurements_terminal():
            return self._run_sweep_sample(resolved_circuit, repetitions)
        return self._run_sweep_repeat(resolved_circuit, repetitions)
Ejemplo n.º 3
0
    def compute_amplitudes_sweep(
        self,
        program: circuits.Circuit,
        bitstrings: Sequence[int],
        params: study.Sweepable,
        qubit_order: ops.QubitOrderOrList = ops.QubitOrder.DEFAULT,
    ) -> Sequence[Sequence[complex]]:
        """Computes the desired amplitudes using qsim.

      The initial state is assumed to be the all zeros state.

      Args:
          program: The circuit to simulate.
          bitstrings: The bitstrings whose amplitudes are desired, input as an
            string array where each string is formed from measured qubit values
            according to `qubit_order` from most to least significant qubit,
            i.e. in big-endian ordering.
          param_resolver: Parameters to run with the program.
          qubit_order: Determines the canonical ordering of the qubits. This is
            often used in specifying the initial state, i.e. the ordering of the
            computational basis states.

      Returns:
          List of amplitudes.
      """
        if not isinstance(program, qsimc.QSimCircuit):
            program = qsimc.QSimCircuit(program, device=program.device)

        n_qubits = len(program.all_qubits())
        # qsim numbers qubits in reverse order from cirq
        bitstrings = [
            format(bitstring, 'b').zfill(n_qubits)[::-1]
            for bitstring in bitstrings
        ]

        options = {'i': '\n'.join(bitstrings)}
        options.update(self.qsim_options)

        param_resolvers = study.to_resolvers(params)

        trials_results = []
        for prs in param_resolvers:

            solved_circuit = protocols.resolve_parameters(program, prs)

            options['c'] = solved_circuit.translate_cirq_to_qsim(qubit_order)
            options['s'] = self.get_seed()

            amplitudes = qsim.qsim_simulate(options)
            trials_results.append(amplitudes)

        return trials_results
Ejemplo n.º 4
0
    def simulate_sweep(
        self,
        program: circuits.Circuit,
        params: study.Sweepable,
        qubit_order: ops.QubitOrderOrList = ops.QubitOrder.DEFAULT,
        initial_state: Any = None,
    ) -> List['SimulationTrialResult']:
        """Simulates the supplied Circuit.

      This method returns a result which allows access to the entire
      wave function. In contrast to simulate, this allows for sweeping
      over different parameter values.

      Args:
          program: The circuit to simulate.
          params: Parameters to run with the program.
          qubit_order: Determines the canonical ordering of the qubits. This is
            often used in specifying the initial state, i.e. the ordering of the
            computational basis states.
          initial_state: The initial state for the simulation. The form of this
            state depends on the simulation implementation.  See documentation
            of the implementing class for details.

      Returns:
          List of SimulationTrialResults for this run, one for each
          possible parameter resolver.
      """
        if not isinstance(program, qsimc.QSimCircuit):
            raise ValueError('{!r} is not a QSimCircuit'.format(program))

        options = {}
        options.update(self.qsim_options)

        param_resolvers = study.to_resolvers(params)

        trials_results = []
        for prs in param_resolvers:
            solved_circuit = protocols.resolve_parameters(program, prs)

            options['c'] = solved_circuit.translate_cirq_to_qsim(qubit_order)

            final_state = qsim.qsim_simulate_fullstate(options)
            assert final_state.dtype == np.float32
            assert final_state.ndim == 1
            # create result for this parameter
            # TODO: We need to support measurements.
            result = SimulationTrialResult(params=prs,
                                           measurements={},
                                           final_simulator_state=final_state)
            trials_results.append(result)

        return trials_results
Ejemplo n.º 5
0
 def _simulator_iterator(
         self,
         circuit: circuits.Circuit,
         param_resolver: study.ParamResolver,
         qubit_order: ops.QubitOrderOrList,
         initial_state: Union[int, np.ndarray],
         perform_measurements: bool = True,
 ) -> Iterator[simulator.StepResult]:
     """See definition in `sim.SimulatesIntermediateWaveFunction`."""
     param_resolver = param_resolver or study.ParamResolver({})
     resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
     return self._base_iterator(resolved_circuit, qubit_order, initial_state,
                                perform_measurements)
Ejemplo n.º 6
0
 def _run(
     self,
     circuit: circuits.Circuit,
     param_resolver: study.ParamResolver,
     repetitions: int) -> Dict[str, List[np.ndarray]]:
     """See definition in `cirq.SimulatesSamples`."""
     param_resolver = param_resolver or study.ParamResolver({})
     resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
     def measure_or_mixture(op):
         return protocols.is_measurement(op) or protocols.has_mixture(op)
     if circuit.are_all_matches_terminal(measure_or_mixture):
         return self._run_sweep_sample(resolved_circuit, repetitions)
     return self._run_sweep_repeat(resolved_circuit, repetitions)
Ejemplo n.º 7
0
def assert_phase_by_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    original = protocols.unitary(val, None)
    if original is None:
        # If there's no unitary, it's vacuously consistent.
        return
    qid_shape = protocols.qid_shape(val,
                                    default=(2, ) *
                                    (len(original).bit_length() - 1))
    original = original.reshape(qid_shape * 2)

    for t in [0.125, -0.25, 1, sympy.Symbol('a'), sympy.Symbol('a') + 1]:
        p = 1j**(t * 4)
        p = protocols.resolve_parameters(p, {'a': -0.125})
        for i in range(len(qid_shape)):
            phased = protocols.phase_by(val, t, i, default=None)
            if phased is None:
                # If not phaseable, then phase_by is vacuously consistent.
                continue

            phased = protocols.resolve_parameters(phased, {'a': -0.125})
            actual = protocols.unitary(phased).reshape(qid_shape * 2)

            expected = np.array(original)
            s = linalg.slice_for_qubits_equal_to([i], 1)
            expected[s] *= p
            s = linalg.slice_for_qubits_equal_to([len(qid_shape) + i], 1)
            expected[s] *= np.conj(p)

            lin_alg_utils.assert_allclose_up_to_global_phase(
                actual,
                expected,
                atol=1e-8,
                err_msg=f'Phased unitary was incorrect for index #{i}',
            )
Ejemplo n.º 8
0
 def _mapped_any_loop(self) -> 'cirq.Circuit':
     circuit = self.circuit.unfreeze()
     if self.qubit_map:
         circuit = circuit.transform_qubits(
             lambda q: self.qubit_map.get(q, q))
     if isinstance(self.repetitions, INT_CLASSES) and self.repetitions < 0:
         circuit = circuit**-1
     if self.measurement_key_map:
         circuit = protocols.with_measurement_key_mapping(
             circuit, self.measurement_key_map)
     if self.param_resolver:
         circuit = protocols.resolve_parameters(circuit,
                                                self.param_resolver,
                                                recursive=False)
     return circuit.unfreeze(copy=False)
Ejemplo n.º 9
0
 def _simulator_iterator(
     self,
     circuit: circuits.Circuit,
     param_resolver: study.ParamResolver,
     qubit_order: ops.QubitOrderOrList,
     initial_state: Union[int, np.ndarray],
     perform_measurements: bool = True,
 ) -> Iterator['XmonStepResult']:
     """See definition in `cirq.SimulatesIntermediateState`."""
     param_resolver = param_resolver or study.ParamResolver({})
     circuit = protocols.resolve_parameters(circuit, param_resolver)
     _verify_xmon_circuit(circuit)
     actual_initial_state = 0 if initial_state is None else initial_state
     return self._base_iterator(circuit, qubit_order, actual_initial_state,
                                perform_measurements)
Ejemplo n.º 10
0
    def _run(self, circuit: circuits.Circuit,
             param_resolver: study.ParamResolver,
             repetitions: int) -> Dict[str, np.ndarray]:
        """See definition in `cirq.SimulatesSamples`."""
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        check_all_resolved(resolved_circuit)

        _, general_suffix = split_into_matching_protocol_then_general(
            resolved_circuit, lambda op: not protocols.is_measurement(op))
        if general_suffix.are_all_measurements_terminal() and not any(
                general_suffix.findall_operations(
                    lambda op: isinstance(op, circuits.CircuitOperation))):
            return self._run_sweep_sample(resolved_circuit, repetitions)
        return self._run_sweep_repeat(resolved_circuit, repetitions)
Ejemplo n.º 11
0
    def _run(
        self,
        circuit: circuits.Circuit,
        param_resolver: study.ParamResolver,
        repetitions: int,
    ) -> Dict[str, List[np.ndarray]]:
        """See definition in `cirq.SimulatesSamples`."""

        circuit = protocols.resolve_parameters(circuit, param_resolver)
        _verify_xmon_circuit(circuit)

        # Delegate to appropriate method based on contents.
        if circuit.are_all_measurements_terminal():
            return self._run_sweep_sample(circuit, repetitions)

        return self._run_sweep_repeat(circuit, repetitions)
Ejemplo n.º 12
0
    def _run(self, circuit: circuits.Circuit,
             param_resolver: study.ParamResolver,
             repetitions: int) -> Dict[str, np.ndarray]:
        """See definition in `cirq.SimulatesSamples`."""
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        check_all_resolved(resolved_circuit)
        qubit_order = sorted(resolved_circuit.all_qubits())

        # Simulate as many unitary operations as possible before having to
        # repeat work for each sample.
        unitary_prefix, general_suffix = (
            split_into_matching_protocol_then_general(resolved_circuit,
                                                      protocols.has_unitary)
            if protocols.has_unitary(self.noise) else
            (resolved_circuit[0:0], resolved_circuit))
        step_result = None
        for step_result in self._base_iterator(
                circuit=unitary_prefix,
                qubit_order=qubit_order,
                initial_state=0,
                perform_measurements=False,
        ):
            pass
        assert step_result is not None

        # When an otherwise unitary circuit ends with non-demolition computation
        # basis measurements, we can sample the results more efficiently.
        general_ops = list(general_suffix.all_operations())
        if all(isinstance(op.gate, ops.MeasurementGate) for op in general_ops):
            return step_result.sample_measurement_ops(
                measurement_ops=cast(List[ops.GateOperation], general_ops),
                repetitions=repetitions,
                seed=self._prng,
            )

        qid_shape = protocols.qid_shape(qubit_order)
        intermediate_state = step_result.state_vector().reshape(qid_shape)
        return self._brute_force_samples(
            initial_state=intermediate_state,
            circuit=general_suffix,
            repetitions=repetitions,
            qubit_order=qubit_order,
        )
Ejemplo n.º 13
0
    def _run(self, circuit: circuits.Circuit,
             param_resolver: study.ParamResolver,
             repetitions: int) -> Dict[str, np.ndarray]:
        """Run a simulation, mimicking quantum hardware.

    Args:
        program: The circuit to simulate.
        param_resolver: Parameters to run with the program.
        repetitions: Number of times to repeat the run.

    Returns:
        A dictionary from measurement gate key to measurement
        results.
    """
        param_resolver = param_resolver or study.ParamResolver({})
        solved_circuit = protocols.resolve_parameters(circuit, param_resolver)

        return self._sample_measure_results(solved_circuit, repetitions)
Ejemplo n.º 14
0
 def _decompose_(self) -> 'cirq.OP_TREE':
     result = self.circuit.unfreeze()
     result = result.transform_qubits(lambda q: self.qubit_map.get(q, q))
     if self.repetitions < 0:
         result = result**-1
     result = protocols.with_measurement_key_mapping(
         result, self.measurement_key_map)
     result = protocols.resolve_parameters(result,
                                           self.param_resolver,
                                           recursive=False)
     # repetition_ids don't need to be taken into account if the circuit has no measurements
     # or if repetition_ids are unset.
     if self.repetition_ids is None or not protocols.is_measurement(result):
         return list(result.all_operations()) * abs(self.repetitions)
     # If it's a measurement circuit with repetitions/repetition_ids, prefix the repetition_ids
     # to measurements. Details at https://tinyurl.com/measurement-repeated-circuitop.
     ops = []  # type: List[cirq.Operation]
     for parent_id in self.repetition_ids:
         for op in result.all_operations():
             if isinstance(op, CircuitOperation):
                 # For a CircuitOperation, prefix the current repetition_id to the children
                 # repetition_ids.
                 ops.append(
                     op.with_repetition_ids(
                         # If `op.repetition_ids` is None, this will return `[parent_id]`.
                         cartesian_product_of_string_lists(
                             [parent_id], op.repetition_ids)))
             elif protocols.is_measurement(op):
                 # For a non-CircuitOperation measurement, prefix the current repetition_id
                 # to the children measurement keys. Implemented by creating a mapping and
                 # using the with_measurement_key_mapping protocol.
                 ops.append(
                     protocols.with_measurement_key_mapping(
                         op,
                         key_map={
                             key:
                             f'{MEASUREMENT_KEY_SEPARATOR.join([parent_id, key])}'
                             for key in protocols.measurement_keys(op)
                         },
                     ))
             else:
                 ops.append(op)
     return ops
Ejemplo n.º 15
0
    def _simulator_iterator(
        self,
        circuit: circuits.Circuit,
        param_resolver: study.ParamResolver,
        qubit_order: ops.QubitOrderOrList,
        initial_state: int,
    ) -> Iterator:
        """See definition in `cirq.SimulatesIntermediateState`.

        Args:
            inital_state: An integer specifying the inital
            state in the computational basis.
        """
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
        self._check_all_resolved(resolved_circuit)
        actual_initial_state = 0 if initial_state is None else initial_state

        return self._base_iterator(resolved_circuit, qubit_order, actual_initial_state)
Ejemplo n.º 16
0
    def _simulator_iterator(self, circuit: circuits.Circuit,
                            param_resolver: study.ParamResolver,
                            qubit_order: ops.QubitOrderOrList,
                            initial_state: Union[int, np.ndarray]) -> Iterator:
        """See definition in `cirq.SimulatesIntermediateState`.

        If the initial state is an int, the state is set to the computational
        basis state corresponding to this state. Otherwise  if the initial
        state is a np.ndarray it is the full initial state, either a pure state
        or the full density matrix.  If it is the pure state it must be the
        correct size, be normalized (an L2 norm of 1), and be safely castable
        to an appropriate dtype for the simulator.  If it is a mixed state
        it must be correctly sized and positive semidefinite with trace one.
        """
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
        actual_initial_state = 0 if initial_state is None else initial_state
        return self._base_iterator(resolved_circuit,
                                   qubit_order,
                                   actual_initial_state)
Ejemplo n.º 17
0
    def transform_params(
            self, params: resolver.ParamResolverOrSimilarType
    ) -> resolver.ParamDictType:
        """Returns a `ParamResolver` to use with a circuit flattened earlier
        with `cirq.flatten`.

        If `params` maps symbol `a` to 3.0 and this `ExpressionMap` maps
        `a/2+1` to `'<a/2 + 1>'` then this method returns a resolver that maps
        symbol `'<a/2 + 1>'` to 2.5.

        See `cirq.flatten` for an example.

        Args:
            params: The params to transform.
        """
        param_dict = {
            sym: protocols.resolve_parameters(formula, params)
            for formula, sym in self.items() if isinstance(sym, sympy.Basic)
        }
        return param_dict
Ejemplo n.º 18
0
    def _make_state_tomography_matrix(self) -> np.ndarray:
        """Gets the matrix used for solving the linear system of the tomography.

        Returns:
            A matrix of dimension ((number of rotations)**n * 2**n, 4**n)
            where each column corresponds to the coefficient of a term in the
            density matrix.  Each row is one equation corresponding to a
            rotation sequence and bit string outcome for that rotation sequence.
        """
        num_rots = len(self.rot_sweep)
        num_states = 2**self.num_qubits

        # Unitary matrices of each rotation circuit.
        unitaries = np.array([
            protocols.unitary(
                protocols.resolve_parameters(self.rot_circuit, rots))
            for rots in self.rot_sweep
        ])
        mat = np.einsum('jkm,jkn->jkmn', unitaries, unitaries.conj())
        return mat.reshape((num_rots * num_states, num_states * num_states))
Ejemplo n.º 19
0
 def _run(self, circuit: circuits.Circuit,
          param_resolver: study.ParamResolver,
          repetitions: int) -> Dict[str, np.ndarray]:
     """See definition in `cirq.SimulatesSamples`."""
     param_resolver = param_resolver or study.ParamResolver({})
     resolved_circuit = protocols.resolve_parameters(
         circuit, param_resolver)
     measurements = {}  # type: Dict[str, List[np.ndarray]]
     # TODO: optimize for all terminal measurements.
     for _ in range(repetitions):
         all_step_results = self._base_iterator(
             resolved_circuit,
             qubit_order=ops.QubitOrder.DEFAULT,
             initial_state=0,
             perform_measurements=True)
         for step_result in all_step_results:
             for k, v in step_result.measurements.items():
                 if not k in measurements:
                     measurements[k] = []
                 measurements[k].append(np.array(v, dtype=bool))
     return {k: np.array(v) for k, v in measurements.items()}
Ejemplo n.º 20
0
 def _decompose_(self) -> 'cirq.OP_TREE':
     result = self.circuit.unfreeze()
     result = result.transform_qubits(lambda q: self.qubit_map.get(q, q))
     if self.repetitions < 0:
         result = result**-1
     result = protocols.with_measurement_key_mapping(
         result, self.measurement_key_map)
     result = protocols.resolve_parameters(result,
                                           self.param_resolver,
                                           recursive=False)
     # repetition_ids don't need to be taken into account if the circuit has no measurements
     # or if repetition_ids are unset.
     if self.repetition_ids is None or not protocols.is_measurement(result):
         return list(result.all_operations()) * abs(self.repetitions)
     # If it's a measurement circuit with repetitions/repetition_ids, prefix the repetition_ids
     # to measurements. Details at https://tinyurl.com/measurement-repeated-circuitop.
     ops = []  # type: List[cirq.Operation]
     for repetition_id in self.repetition_ids:
         path = self.parent_path + (repetition_id, )
         ops += protocols.with_key_path(result, path).all_operations()
     return ops
Ejemplo n.º 21
0
    def _validate_operation(self, op: raw_types.Operation) -> bool:
        """Validates whether the given `cirq.Operation` is contained in this Gateset.

        The containment checks are handled as follows:

        a) For any operation which has an underlying gate (i.e. `op.gate` is not None):
            - Containment is checked via `self.__contains__` which further checks for containment
                in any of the underlying gate families.

        b) For all other types of operations (eg: `cirq.CircuitOperation`,
        `cirq.GlobalPhaseOperation` etc):
            - The behavior is controlled via flags passed to the constructor.

        Users should override this method to define custom behavior for operations that do not
        have an underlying `cirq.Gate`.

        Args:
            op: The `cirq.Operation` instance to check containment for.
        """

        # To avoid circular import.
        from cirq.circuits import circuit_operation

        if op.gate is not None:
            return op in self

        if isinstance(op, raw_types.TaggedOperation):
            return self._validate_operation(op.sub_operation)
        elif isinstance(op, circuit_operation.CircuitOperation
                        ) and self._unroll_circuit_op:
            op_circuit = protocols.resolve_parameters(op.circuit.unfreeze(),
                                                      op.param_resolver,
                                                      recursive=False)
            op_circuit = op_circuit.transform_qubits(lambda q: cast(
                circuit_operation.CircuitOperation, op).qubit_map.get(q, q))
            return self.validate(op_circuit)
        elif isinstance(op, global_phase_op.GlobalPhaseOperation):
            return self._accept_global_phase_op
        else:
            return False
Ejemplo n.º 22
0
    def _run(self, circuit: circuits.Circuit,
             param_resolver: study.ParamResolver,
             repetitions: int) -> Dict[str, List[np.ndarray]]:
        """Repeats measurements multiple times.

        Args:
            circuit: The circuit to simulate.
            param_resolver: A ParamResolver for determining values of
                Symbols.
            repetitions: How many measurements to perform
            final_simulator_state: The final state of the simulator.

        Returns:
            A dictionay of measurement key (e.g. qubit) to a list of arrays that
            are the measurements.
        """
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        self._check_all_resolved(resolved_circuit)

        measurements = {}  # type: Dict[str, List[np.ndarray]]
        if repetitions == 0:
            for _, op, _ in resolved_circuit.findall_operations_with_gate_type(
                    ops.MeasurementGate):
                measurements[protocols.measurement_key(op)] = np.empty([0, 1])

        for _ in range(repetitions):
            all_step_results = self._base_iterator(
                resolved_circuit,
                qubit_order=ops.QubitOrder.DEFAULT,
                initial_state=0)

            for step_result in all_step_results:
                for k, v in step_result.measurements.items():
                    if not k in measurements:
                        measurements[k] = []
                    measurements[k].append(np.array(v, dtype=int))

        return {k: np.array(v) for k, v in measurements.items()}
Ejemplo n.º 23
0
    def mapped_circuit(self, deep: bool = False) -> 'cirq.Circuit':
        """Applies all maps to the contained circuit and returns the result.

        Args:
            deep: If true, this will also call mapped_circuit on any
                CircuitOperations this object contains.

        Returns:
            The contained circuit with all other member variables (repetitions,
            qubit mapping, parameterization, etc.) applied to it. This behaves
            like `cirq.decompose(self)`, but preserving moment structure.
        """
        circuit = self.circuit.unfreeze()
        if self.qubit_map:
            circuit = circuit.transform_qubits(
                lambda q: self.qubit_map.get(q, q))
        if self.repetitions < 0:
            circuit = circuit**-1
        if self.measurement_key_map:
            circuit = protocols.with_measurement_key_mapping(
                circuit, self.measurement_key_map)
        if self.param_resolver:
            circuit = protocols.resolve_parameters(circuit,
                                                   self.param_resolver,
                                                   recursive=False)
        if self.repetition_ids:
            if not protocols.is_measurement(circuit):
                circuit = circuit * abs(self.repetitions)
            else:
                circuit = circuits.Circuit(
                    protocols.with_rescoped_keys(circuit, (rep, ))
                    for rep in self.repetition_ids)
        circuit = protocols.with_rescoped_keys(circuit,
                                               self.parent_path,
                                               bindable_keys=self.extern_keys)
        if deep:
            circuit = circuit.map_operations(lambda op: op.mapped_circuit(
                deep=True) if isinstance(op, CircuitOperation) else op)
        return circuit
Ejemplo n.º 24
0
    def _run(
        self, circuit: circuits.Circuit, param_resolver: study.ParamResolver, repetitions: int
    ) -> Dict[str, List[np.ndarray]]:

        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
        check_all_resolved(resolved_circuit)

        measurements = {}  # type: Dict[str, List[np.ndarray]]

        for _ in range(repetitions):
            all_step_results = self._base_iterator(
                resolved_circuit, qubit_order=ops.QubitOrder.DEFAULT, initial_state=0
            )

            for step_result in all_step_results:
                for k, v in step_result.measurements.items():
                    if not k in measurements:
                        measurements[k] = []
                    measurements[k].append(np.array(v, dtype=bool))

        return {k: np.array(v) for k, v in measurements.items()}
Ejemplo n.º 25
0
    def with_params(self, param_values: study.ParamResolverOrSimilarType) -> 'CircuitOperation':
        """Returns a copy of this operation with an updated ParamResolver.

        Note that any resulting parameter mappings with no corresponding
        parameter in the base circuit will be omitted.

        Args:
            param_values: A map or ParamResolver able to convert old param
                values to new param values. This map will be composed with any
                existing ParamResolver via single-step resolution.

        Returns:
            A copy of this operation with its ParamResolver updated as specified
                by param_values.
        """
        new_params = {}
        for k in protocols.parameter_symbols(self.circuit):
            v = self.param_resolver.value_of(k, recursive=False)
            v = protocols.resolve_parameters(v, param_values, recursive=False)
            if v != k:
                new_params[k] = v
        return self.replace(param_resolver=new_params)
Ejemplo n.º 26
0
    def _simulator_iterator(
        self,
        circuit: circuits.Circuit,
        param_resolver: study.ParamResolver,
        qubit_order: ops.QubitOrderOrList,
        initial_state: Any,
    ) -> Iterator:
        """Iterator over StepResult from Moments of a Circuit.

        If the initial state is an int, the state is set to the computational
        basis state corresponding to this state. Otherwise if the initial
        state is a np.ndarray it is the full initial state, either a pure state
        or the full density matrix.  If it is the pure state it must be the
        correct size, be normalized (an L2 norm of 1), and be safely castable
        to an appropriate dtype for the simulator.  If it is a mixed state
        it must be correctly sized and positive semidefinite with trace one.

        Args:
            circuit: The circuit to simulate.
            param_resolver: A ParamResolver for determining values of
                Symbols.
            qubit_order: Determines the canonical ordering of the qubits. This
                is often used in specifying the initial state, i.e. the
                ordering of the computational basis states.
            initial_state: The initial state for the simulation. The form of
                this state depends on the simulation implementation. See
                documentation of the implementing class for details.

        Yields:
            StepResults from simulating a Moment of the Circuit.
        """
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        check_all_resolved(resolved_circuit)
        actual_initial_state = 0 if initial_state is None else initial_state
        return self._base_iterator(resolved_circuit, qubit_order,
                                   actual_initial_state)
Ejemplo n.º 27
0
    def _simulator_iterator(
            self,
            circuit: circuits.Circuit,
            param_resolver: study.ParamResolver,
            qubit_order: ops.QubitOrderOrList,
            initial_state: 'cirq.STATE_VECTOR_LIKE',
    ) -> Iterator:
        """See definition in `cirq.SimulatesIntermediateState`.

        If the initial state is an int, the state is set to the computational
        basis state corresponding to this state. Otherwise  if the initial
        state is a np.ndarray it is the full initial state. In this case it
        must be the correct size, be normalized (an L2 norm of 1), and
        be safely castable to an appropriate dtype for the simulator.
        """
        param_resolver = param_resolver or study.ParamResolver({})
        resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
        self._check_all_resolved(resolved_circuit)
        actual_initial_state = 0 if initial_state is None else initial_state
        return self._base_iterator(resolved_circuit,
                                   qubit_order,
                                   actual_initial_state,
                                   perform_measurements=True)
Ejemplo n.º 28
0
    def simulate_moment_steps(
        self,
        circuit: 'cirq.AbstractCircuit',
        param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
        qubit_order: 'cirq.QubitOrderOrList' = ops.QubitOrder.DEFAULT,
        initial_state: Any = None,
    ) -> Iterator[TStepResult]:
        """Returns an iterator of StepResults for each moment simulated.

        If the circuit being simulated is empty, a single step result should
        be returned with the state being set to the initial state.

        Args:
            circuit: The Circuit to simulate.
            param_resolver: A ParamResolver for determining values of Symbols.
            qubit_order: Determines the canonical ordering of the qubits. This
                is often used in specifying the initial state, i.e. the
                ordering of the computational basis states.
            initial_state: The initial state for the simulation. This can be
                either a raw state or a `TSimulationState`. The form of the
                raw state depends on the simulation implementation. See
                documentation of the implementing class for details.

        Returns:
            Iterator that steps through the simulation, simulating each
            moment and returning a StepResult for each moment.
        """
        param_resolver = study.ParamResolver(param_resolver)
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        check_all_resolved(resolved_circuit)
        actual_initial_state = 0 if initial_state is None else initial_state
        qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
            circuit.all_qubits())
        return self._base_iterator(resolved_circuit, qubits,
                                   actual_initial_state)
Ejemplo n.º 29
0
    def with_params(self,
                    param_values: 'cirq.ParamResolverOrSimilarType',
                    recursive: bool = False) -> 'cirq.CircuitOperation':
        """Returns a copy of this operation with an updated ParamResolver.

        Any existing parameter mappings will have their values updated given
        the provided mapping, and any new parameters will be added to the
        ParamResolver.

        Note that any resulting parameter mappings with no corresponding
        parameter in the base circuit will be omitted. These parameters do not
        apply to the `repetitions` field if that is parameterized.

        Args:
            param_values: A map or ParamResolver able to convert old param
                values to new param values. This map will be composed with any
                existing ParamResolver via single-step resolution.
            recursive: If True, resolves parameter values recursively over the
                resolver; otherwise performs a single resolution step. This
                behavior applies only to the passed-in mapping, for the current
                application. Existing parameters are never resolved recursively
                because a->b and b->a needs to be a valid mapping.

        Returns:
            A copy of this operation with its ParamResolver updated as specified
                by param_values.
        """
        new_params = {}
        for k in protocols.parameter_symbols(self.circuit):
            v = self.param_resolver.value_of(k, recursive=False)
            v = protocols.resolve_parameters(v,
                                             param_values,
                                             recursive=recursive)
            if v != k:
                new_params[k] = v
        return self.replace(param_resolver=new_params)
Ejemplo n.º 30
0
    def run(
        self,
        circuit: 'cirq.Circuit',
        repetitions: int,
        name: Optional[str] = None,
        target: Optional[str] = None,
        param_resolver: study.ParamResolverOrSimilarType = study.ParamResolver(
            {}),
        seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
    ) -> study.Result:
        """Run the given circuit on the IonQ API.

        Args:
            circuit: The circuit to run.
            repetitions: The number of times to run the circuit.
            name: An optional name for the created job. Different from the `job_id`.
            target: Where to run the job. Can be 'qpu' or 'simulator'.
            param_resolver: A `cirq.ParamResolver` to resolve parameters in  `circuit`.
            seed: If the target is `simulation` the seed for generating results. If None, this
                will be `np.random`, if an int, will be `np.random.RandomState(int)`, otherwise
                must be a modulate similar to `np.random`.

        Returns:
            A `cirq.Result` for running the circuit.
        """
        resolved_circuit = protocols.resolve_parameters(
            circuit, param_resolver)
        result = self.create_job(resolved_circuit, repetitions, name,
                                 target).results()
        if isinstance(result, results.QPUResult):
            return result.to_cirq_result(
                params=study.ParamResolver(param_resolver))
        else:
            sim_result = cast(results.SimulatorResult, result)
            return sim_result.to_cirq_result(
                params=study.ParamResolver(param_resolver), seed=seed)