in tensorflow_quantum/python/layers/high_level/noisy_controlled_pqc.py [0:0]
def __init__(self,
model_circuit,
operators,
*,
repetitions=None,
sample_based=None,
differentiator=None,
**kwargs):
"""Instantiate this layer.
Create a layer that will output noisy expectation values of the given
operators when fed quantum data to it's input layer. This layer will
take two input tensors, one representing a quantum data source (these
circuits must not contain any symbols) and the other representing
control parameters for the model circuit that gets appended to the
datapoints.
model_circuit: `cirq.Circuit` containing `sympy.Symbols` that will be
used as the model which will be fed quantum data inputs.
operators: `cirq.PauliSum` or Python `list` of `cirq.PauliSum` objects
used as observables at the end of the model circuit.
repetitions: Python `int` indicating how many trajectories to use
when estimating expectation values.
sample_based: Python `bool` indicating whether to use sampling to
estimate expectations or analytic calculations with each
trajectory.
differentiator: Optional `tfq.differentiator` object to specify how
gradients of `model_circuit` should be calculated.
"""
super().__init__(**kwargs)
# Ingest model_circuit.
if not isinstance(model_circuit, cirq.Circuit):
raise TypeError("model_circuit must be a cirq.Circuit object."
" Given: ".format(model_circuit))
self._symbols_list = list(
sorted(util.get_circuit_symbols(model_circuit)))
self._symbols = tf.constant([str(x) for x in self._symbols_list])
self._circuit = util.convert_to_tensor([model_circuit])
if len(self._symbols_list) == 0:
raise ValueError("model_circuit has no sympy.Symbols. Please "
"provide a circuit that contains symbols so "
"that their values can be trained.")
# Ingest operators.
if isinstance(operators, (cirq.PauliString, cirq.PauliSum)):
operators = [operators]
if not isinstance(operators, (list, np.ndarray, tuple)):
raise TypeError("operators must be a cirq.PauliSum or "
"cirq.PauliString, or a list, tuple, "
"or np.array containing them. "
"Got {}.".format(type(operators)))
if not all([
isinstance(op, (cirq.PauliString, cirq.PauliSum))
for op in operators
]):
raise TypeError("Each element in operators to measure "
"must be a cirq.PauliString"
" or cirq.PauliSum")
self._operators = util.convert_to_tensor([operators])
# Ingest and promote repetitions.
if repetitions is None:
raise ValueError("Value for repetitions must be provided when "
"using noisy simulation.")
if not isinstance(repetitions, numbers.Integral):
raise TypeError("repetitions must be a positive integer value."
" Given: ".format(repetitions))
if repetitions <= 0:
raise ValueError("Repetitions must be greater than zero.")
self._repetitions = tf.constant(
[[repetitions for _ in range(len(operators))]],
dtype=tf.dtypes.int32)
# Ingest differentiator.
if differentiator is None:
differentiator = parameter_shift.ParameterShift()
# Ingest and promote sample based.
if sample_based is None:
raise ValueError("Please specify sample_based=False for analytic "
"calculations based on monte-carlo trajectories,"
" or sampled_based=True for measurement based "
"noisy estimates.")
if not isinstance(sample_based, bool):
raise TypeError("sample_based must be either True or False."
" received: {}".format(type(sample_based)))
if not sample_based:
self._executor = differentiator.generate_differentiable_op(
sampled_op=noisy_expectation_op.expectation)
else:
self._executor = differentiator.generate_differentiable_op(
sampled_op=noisy_sampled_expectation_op.sampled_expectation)
self._append_layer = elementary.AddCircuit()