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)
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)
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
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
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)
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)
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}', )
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)
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)
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)
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)
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, )
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)
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
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)
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)
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
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))
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()}
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
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
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()}
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
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()}
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)
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)
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)
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)
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)
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)