# Custom gate with a matrix

**URL:** https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773
**Category:** PennyLane Help
**Created:** [December 4, 2023, 8:42pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773 "2023-12-04T20:42:23Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![sdas](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/sdas/32/1615_2.png) [@sdas](https://discuss.pennylane.ai/u/sdas)
#### Post date: [December 4, 2023, 8:42pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/1 "2023-12-04T20:42:23Z")

</div>

HI, I am creating a custom gate using a unitary matrix A.

```auto
class transform_matrix(Operation):

    num_params = 0
    num_wires = 10
    par_domain = None

    @staticmethod
    def _matrix(self):
        s1 = np.matrix([[0,1],[1,0]])
        ID = np.identity(2)
        A_1 = np.array(np.zeros((64, 64)))
        for i in range(0, 64, 1):
            if i//32 == 0:
                A_1[i, 2*i+1] = 1
            elif i//32 == 1:
                A_1[i, 64-2*(i%32)-2] = 1

        A = np.kron(A_1, np.kron(np.kron(s1, s1), np.kron(s1, s1)))
        return np.array(A)

```

Then I add it to the device using:

```auto
dev = qml.device('default.qubit', wires = 10)
dev.operations.add("transform_matrix")

```

When I call it as following

```auto
transform_matrix(wires=[i for i in range(10)])

```

it shows this error

```auto
pennylane.operation.MatrixUndefinedError

```

Can someone tell me where I am wrong?

---

<div class="post-metadata">

### Author: ![isaacdevlugt](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/isaacdevlugt/32/1159_2.png) [@isaacdevlugt](https://discuss.pennylane.ai/u/isaacdevlugt)
#### Post date: [December 4, 2023, 9:01pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/2 "2023-12-04T21:01:00Z")

</div>

Hey @sdas!

Quick aside: I’m running the most updated version of PennyLane (v0.33) and this code won’t work because of device API changes that were made a couple releases ago. If you decide to update (which I recommend that you do!) you just need to change your device to use the old default qubit:

```auto
dev = qml.device('default.qubit.legacy', wires = 10)

```

If I change that and run on v0.33, your code works and I get

```auto
transform_matrix(wires=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

```

Having said that, I think you should create your custom operation differently 🙂. Check out this documentation page for an example: [Adding new operators — PennyLane 0.33.0 documentation](https://docs.pennylane.ai/en/stable/development/adding_operators.html?highlight=custom%20operators#creating-custom-operators).

Let me know if this helps!

---

<div class="post-metadata">

### Author: ![sdas](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/sdas/32/1615_2.png) [@sdas](https://discuss.pennylane.ai/u/sdas)
#### Post date: [December 4, 2023, 10:56pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/3 "2023-12-04T22:56:34Z")

</div>

Thanks Issacdevlugt. If I understood correctly, I upgraded pennylane to v0.33.1 and only changed “default.qubit” to “default.qubit.legacy”. But now it shows,

File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/ **init**.py”, line 337, in device  
raise DeviceError(“Device does not exist. Make sure the required plugin is installed.”)  
pennylane.\_device.DeviceError: Device does not exist. Make sure the required plugin is installed.

---

<div class="post-metadata">

### Author: ![sdas](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/sdas/32/1615_2.png) [@sdas](https://discuss.pennylane.ai/u/sdas)
#### Post date: [December 4, 2023, 11:14pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/4 "2023-12-04T23:14:36Z")

</div>

Sorry there was a mistake in the upgrading process. Trying the solution now after correct upgrade.

---

<div class="post-metadata">

### Author: ![sdas](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/sdas/32/1615_2.png) [@sdas](https://discuss.pennylane.ai/u/sdas)
#### Post date: [December 4, 2023, 11:24pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/5 "2023-12-04T23:24:54Z")

</div>

So after I update the version and change “default.qubit” to “default.qubit.legacy” and run the code, it is showing same error,

pennylane.operation.MatrixUndefinedError

In detail,

File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/qnode.py”, line 1027, in **call**  
res = qml.execute(  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/interfaces/execution.py”, line 616, in execute  
results = inner\_execute(tapes)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/interfaces/execution.py”, line 249, in inner\_execute  
return cached\_device\_execution(tapes)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/interfaces/execution.py”, line 371, in wrapper  
res = list(fn(tuple(execution\_tapes.values()), \*\*kwargs))  
File “/home/sd/anaconda3/lib/python3.9/contextlib.py”, line 79, in inner  
return func(\*args, \*\*kwds)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/\_qubit\_device.py”, line 460, in batch\_execute  
res = self.execute(circuit)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/\_qubit\_device.py”, line 279, in execute  
self.apply(circuit.operations, rotations=self.\_get\_diagonalizing\_gates(circuit), \*\*kwargs)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/devices/default\_qubit\_legacy.py”, line 296, in apply  
self.\_state = self.\_apply\_operation(self.\_state, operation)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/devices/default\_qubit\_legacy.py”, line 338, in \_apply\_operation  
matrix = self.\_asarray(self.\_get\_unitary\_matrix(operation), dtype=self.C\_DTYPE)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/devices/default\_qubit\_legacy.py”, line 682, in \_get\_unitary\_matrix  
return unitary.matrix()  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/operation.py”, line 775, in matrix  
canonical\_matrix = self.compute\_matrix(\*self.parameters, \*\*self.hyperparameters)  
File “/home/sd/anaconda3/lib/python3.9/site-packages/pennylane/operation.py”, line 744, in compute\_matrix  
raise MatrixUndefinedError  
pennylane.operation.MatrixUndefinedError

---

<div class="post-metadata">

### Author: ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)
#### Post date: [December 5, 2023, 2:39pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/6 "2023-12-05T14:39:36Z")

</div>

Hi @sdas!

The following will work with the (non-legacy) `default.qubit` and the latest release of PennyLane:

```python
import pennylane as qml
from pennylane.operation import Operation
from pennylane import numpy as np

class transform_matrix(Operation):

    num_params = 0
    num_wires = 10
    par_domain = None

    @staticmethod
    def compute_matrix():
        s1 = np.matrix([[0,1],[1,0]])
        ID = np.identity(2)
        A_1 = np.array(np.zeros((64, 64)))
        for i in range(0, 64, 1):
            if i//32 == 0:
                A_1[i, 2*i+1] = 1
            elif i//32 == 1:
                A_1[i, 64-2*(i%32)-2] = 1

        A = np.kron(A_1, np.kron(np.kron(s1, s1), np.kron(s1, s1)))
        return np.array(A)

dev = qml.device("default.qubit")

@qml.qnode(dev)
def f():
    transform_matrix(wires=range(10))
    return qml.state()

f()

```

Here, the trick is to override the `compute_matrix()` static method.

---

<div class="post-metadata">

### Author: ![sdas](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/sdas/32/1615_2.png) [@sdas](https://discuss.pennylane.ai/u/sdas)
#### Post date: [December 5, 2023, 5:25pm UTC](https://discuss.pennylane.ai/t/custom-gate-with-a-matrix/3773/7 "2023-12-05T17:25:10Z")

</div>

Hi @Tom_Bromley  
It is working now, thanks!
