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?