In a @transform I would like to go through a tape and change the parameters of some types of gates. I thought this should be easy but it is not, or I am too stupid…
The general structure of my transform is as follows:
new_operations = list()
for operation in tape.operations:
update_operation = [...]
new_operations.append(update_operation)
new_tape = type(tape)(new_operations, tape.measurements, shots=tape.shots)
def postprocessing(results):
return np.array(results)[0]
return [new_tape], postprocessing
My problem is with the update_operation = [...]
part. I would like this to work for general operations that have a single parameter.
My first idea was to simply make a copy of operation
with copy.deepcopy()
and then modify its .parameters
, but the property cannot be set.
My second idea was to call the constructor of the class of operation with something like:
operation.__class__(
*new_parameters,
**operation.hyperparameters,
wires=operation.wires,
)
But this does not work for Adjoint
operations. Of course I can add a if statement to treat that case (not elegant), but then it still does not work for controlled operations like qml.CRX
because
print(qml.CRX(0.2, [0, 1]).hyperparameters)
{'control_wires': Wires([0]), 'control_values': [True], 'work_wires': Wires([]), 'base': RX(0.2, wires=[1])}
Is there an elegant way to take any operation that can appear on a tape and get a copy with modified parameters
?