Hi, I’m working on a project for quantum computer synthesis with ES and look for an efficient way to specifically exchange operation on different wires and different places. I looked through the docs and have some ideas how it could work, but they feel like I miss a crucial part to make it elegant. Is there a trivial way I missed doing such a transformation of operators, or do I have to glue something together till it works ?

Also, I’m thinking about changing from generator random qnodes to instantly generating random tapes to save some unneeded code. Is there a direct answer if you can do everything with tape what would be possible in qnodes or are there clear limitations why it would be a bad idea. I can solve this answers myself, but it doesn’t hurt asking if there is a clear answer to this

Here is the current generator

```
import pennylane as qml
from pennylane import numpy as np
from pennylane.ops import CNOT
def random_qnode(num_wires, gate_set, min_depth, max_depth):
# Create a quantum device with the specified number of wires
dev = qml.device("default.qubit", wires=num_wires)
# Define a quantum circuit using the PennyLane QNode decorator
@qml.simplify
@qml.qnode(dev)
def circuit():
# Randomly choose the depth of the quantum circuit
depth = np.random.randint(min_depth, max_depth + 1)
# Iterate over the chosen depth
for _ in range(depth):
# Iterate over each wire in the quantum device
for wire in range(num_wires):
# Randomly choose a gate from the specified gate_set
gate_class = np.random.choice(gate_set)
# Special case if CNOT gate is chosen
if gate_class is CNOT:
# Get a list of all wires and remove the control wire
possible_target_wire = list(range(num_wires))
possible_target_wire.remove(wire)
# Randomly choose a target wire from the remaining wires
target_wire = np.random.choice(possible_target_wire)
# Apply CNOT gate to the chosen wire pair
CNOT([wire, target_wire])
else:
# Apply the chosen gate to a single wire
gate_class(wire)
# Return a list of expected values of PauliZ for each wire
return qml.state()
# Return the constructed quantum circuit
return circuit
```

Here is the function which would change operations, still work in progress:

```
import pennylane as qml
import random
from pennylane import numpy as np
def mutation(m_qnode:qml.qnode, mutation_cap = 1):
gates_applied = m_qnode.qtape.operations
m_amount_nbr = random.choice(range(len(gates_applied)-mutation_cap))
m_rows = []
m_possible_rows = list(range(len(gates_applied)))
for i in range(m_amount_nbr):
rdm_possible_row = random.choice(m_possible_rows)
m_possible_rows.remove(rdm_possible_row)
wires = len(m_qnode.qtape.op_wires())
#TODO code to exchange differnet parts of the given circuit
```

And, finally, make sure to include the versions of your packages. Specifically, show us the output of `qml.about()`

.

Name: PennyLane

Version: 0.33.0

Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.

Home-page: GitHub - PennyLaneAI/pennylane: PennyLane is a cross-platform Python library for differentiable programming of quantum computers. Train a quantum computer the same way as a neural network.

Author:

Author-email:

License: Apache License 2.0

Location: c:\users\tombi\pycharmprojects\venv\lib\site-packages

Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions

Required-by: PennyLane-Lightning

Platform info: Windows-10-10.0.22621-SP0

Python version: 3.9.13

Numpy version: 1.26.1

Scipy version: 1.11.3

Installed devices:

- default.gaussian (PennyLane-0.33.0)
- default.mixed (PennyLane-0.33.0)
- default.qubit (PennyLane-0.33.0)
- default.qubit.autograd (PennyLane-0.33.0)
- default.qubit.jax (PennyLane-0.33.0)
- default.qubit.legacy (PennyLane-0.33.0)
- default.qubit.tf (PennyLane-0.33.0)
- default.qubit.torch (PennyLane-0.33.0)
- default.qutrit (PennyLane-0.33.0)
- null.qubit (PennyLane-0.33.0)
- lightning.qubit (PennyLane-Lightning-0.33.1)

Process finished with exit code 0