I am trying to implement a custom gate. The gate have a matrix like this:
def matrix(theta):
a = np.cos(theta)
b = np.sin(theta)
A = [[1, 0, 0, 0],
[0, a, b, 0],
[0, -b, a, 0],
[0, 0, 0, 1]]
return A
i checked your link about how to add custom gates and templates to Pennylane here: How to add custom gates and templates to PennyLane
Here is my implementation:
import pennylane as qml
from pennylane import numpy as np
from pennylane.operation import Operation, AnyWires
class MyGate(Operation):
num_params = 1 # The template takes one parameters.
num_wires = AnyWires # The template works for any number of wires.
par_domain = “R”
def expand(self):
with qml.tape.QuantumTape() as tape:
# Iterate over all qubit pairs
for i in range(len(self.wires)):
qml.Hadamard(wires=[self.wires[i]])
qml.Hadamard(wires = [self.wires[i + 1]])
qml.CZ(wires=[self.wires[i], self.wires[i+1]])
qml.RY(self.data[0]/2, self.wires[i])
qml.RY(-self.data[0]/2, self.wires[i+1])
qml.CZ(wires=[self.wires[i], self.wires[i+1]])
qml.Hadamard(wires=[self.wires[i]])
qml.Hadamard(wires = [self.wires[i + 1]])
return tape
above, i decomposed the gate corresponding to the matrix A.
dev = qml.device(‘default.qubit’, wires=4)
dev.operations.add(“MyGate”)
and then
@qml.qnode(dev)
def circuit(theta):
MyGate(theta[0], wires=[0, 2])
MyGate(theta[1], wires=[0, 1])
MyGate(theta[2], wires=[2, 3])
return qml.state()
theta = [0.42053434, 2.03444394, 3.14159265]
print(circuit(theta))
. I encountered this error:
MatrixUndefinedError Traceback (most recent call last)
/tmp/ipykernel_58390/1607498551.py in
1 theta = [0.42053434, 2.03444394, 3.14159265]
2
----> 3 print(circuit(theta))
~/anaconda3/lib/python3.7/site-packages/pennylane/qnode.py in call(self, *args, **kwargs)
666 gradient_kwargs=self.gradient_kwargs,
667 override_shots=override_shots,
→ 668 **self.execute_kwargs,
669 )
670
~/anaconda3/lib/python3.7/site-packages/pennylane/interfaces/execution.py in execute(tapes, device, gradient_fn, interface, mode, gradient_kwargs, cache, cachesize, max_diff, override_shots, expand_fn, max_expansion, device_batch_transform)
370 qml.interfaces.cache_execute(
371 batch_execute, cache, return_tuple=False, expand_fn=expand_fn
→ 372 )(tapes)
373 )
374
~/anaconda3/lib/python3.7/site-packages/pennylane/interfaces/execution.py in wrapper(tapes, **kwargs)
195 else:
196 # execute all unique tapes that do not exist in the cache
→ 197 res = fn(execution_tapes.values(), **kwargs)
198
199 final_res =
~/anaconda3/lib/python3.7/site-packages/pennylane/interfaces/execution.py in fn(tapes, **kwargs)
120 def fn(tapes, **kwargs): # pylint: disable=function-redefined
121 tapes = [expand_fn(tape) for tape in tapes]
→ 122 return original_fn(tapes, **kwargs)
123
124 @wraps(fn)
~/anaconda3/lib/python3.7/contextlib.py in inner(*args, **kwds)
72 def inner(*args, **kwds):
73 with self._recreate_cm():
—> 74 return func(*args, **kwds)
75 return inner
76
~/anaconda3/lib/python3.7/site-packages/pennylane/_qubit_device.py in batch_execute(self, circuits)
584
585 # TODO: Insert control on value here
→ 586 res = self.execute(circuit)
587 results.append(res)
588
~/anaconda3/lib/python3.7/site-packages/pennylane/_qubit_device.py in execute(self, circuit, **kwargs)
313
314 # apply all circuit operations
→ 315 self.apply(circuit.operations, rotations=circuit.diagonalizing_gates, **kwargs)
316
317 # generate computational basis samples
~/anaconda3/lib/python3.7/site-packages/pennylane/devices/default_qubit.py in apply(self, operations, rotations, **kwargs)
255 self._debugger.snapshots[len(self._debugger.snapshots)] = state_vector
256 else:
→ 257 self._state = self._apply_operation(self._state, operation)
258
259 # store the pre-rotated state
~/anaconda3/lib/python3.7/site-packages/pennylane/devices/default_qubit.py in _apply_operation(self, state, operation)
283 return self._apply_ops[operation.base_name](state, axes, inverse=operation.inverse)
284
→ 285 matrix = self._asarray(self._get_unitary_matrix(operation), dtype=self.C_DTYPE)
286
287 if operation in diagonal_in_z_basis:
~/anaconda3/lib/python3.7/site-packages/pennylane/devices/default_qubit.py in _get_unitary_matrix(self, unitary)
617 return unitary.eigvals()
618
→ 619 return unitary.matrix()
620
621 @classmethod
~/anaconda3/lib/python3.7/site-packages/pennylane/operation.py in matrix(self, wire_order)
1389
1390 def matrix(self, wire_order=None):
→ 1391 canonical_matrix = self.compute_matrix(*self.parameters, **self.hyperparameters)
1392
1393 if self.inverse:
~/anaconda3/lib/python3.7/site-packages/pennylane/operation.py in compute_matrix(*params, **hyperparams)
458 tensor_like: matrix representation
459 “”"
→ 460 raise MatrixUndefinedError
461
462 # pylint: disable=no-self-argument, comparison-with-callable
MatrixUndefinedError:
many thanks in advance for helping me.