## Modifiers and Custom Gates

### Gate Modifiers

Scotty provides two modifiers that can be applied to some gates: `Controlled`

and `Dagger`

.

`Controlled`

implements the `ControlGate`

trait. You can use it by setting the control index and the target gate. The target gate can be a controlled gate or a target gate (but not a swap gate). The simulator allows for as many qubits in between control and target qubit indexes as you want. You can also have qubits set in any order.

`Dagger`

is a modifier that takes the complex conjugate transpose of a single-qubit gate matrix.

You can mix and match modifiers and gates in any way you see fit as long as the final controlled gate is a `TargetGate`

:

```
Controlled(0, Dagger(Y(1))
```

### Custom Gates

Scotty provides two abstractions for custom gates: `DefGate`

and `CompositeGate`

. `DefGate`

lets you to define single-qubit gates with your own matrix.

Here is how you can define a simple square root of NOT gate:

```
import scotty.quantum.math.Complex
val matrix = Array(
Array(Complex(0.5, 0.5), Complex(0.5, -0.5)),
Array(Complex(0.5, -0.5), Complex(0.5, 0.5))
).toFloat
def SqrtNot(index: Int) = DefGate(matrix, index)
```

Now you can use `SqrtNot`

as any other gate:

```
QuantumSimulator().run(Circuit(X(1), SqrtNot(1)))
```

`Complex`

is a complex number representation provided by the framework. It has two `Float`

parameters: one for the real part and one for the imaginary part. Gates use a more bare-bones representation of the matrix for performance reasons: `Array[Array[Float]]`

. It represents complex numbers by putting real and imaginary float components next to each other. You can still define your gates with the `Complex`

helper but you have to use the implicit `toFloat`

method to convert your matrix array before passing it to `DefGate`

.

To define a custom parametric gate use another `DefGate`

constructor that takes a `MatrixGen`

(which is a shorthand for type `Seq[Float] => Matrix`

) and a list of `Double`

parameters. Here’s an example of a custom phase shift gate:

```
import scotty.quantum.math.Complex
val matrix = (params: Seq[Double]) => Array(
Array(Complex(1), Complex(0)),
Array(Complex(0), Complex(Math.cos(params(0)), Math.sin(params(0))))
).toFloat
def QuarterPhase(phi: Double, index: Int) = DefGate(matrix, phi / 4, index)
```

Here’s how you can use it:

```
QuarterPhase(Math.PI, 0)
```

Finally, you can define `CompositeGate`

s to describe multi-qubit unitary gates. Some gates in the Scotty simulator use this technique. For example, the `SWAP`

gate is implemented as a function that takes custom indexes as two parameters and returns a `CompositeGate`

:

```
def SWAP(i0: Int, i1: Int) = CompositeGate(CNOT(i0, i1), CNOT(i1, i0), CNOT(i0, i1))
```

You can use this approach to define your own gates and unitary operations.

- Getting Started
- Quantum Context and Simulator
- Circuits and Qubits
- Superposition and Measurement
- Operations
- Standard Gates
- Modifiers and Custom Gates
- State Readers