# Entanglers

The Classiq entangler tools include three entangler functions designed for creating entangled state vectors. All entanglers construct graph states [1] , according to specific types of graphs, when applied to the all-zero (\(\ket{0}...\ket{0}\)) state vector. A graph state \(\ket{G}\) corresponding to graph G = (V,E) is defined as:

The graph state is prepared by first applying Hadamard gates to all qubits in the graph, which correspond to the nodes in V, and then applying CZ gates to qubit pairs which correspond to the edges in E. Note that the CZ operations commute, and therefore the order in which they are applied does not affect the output state of the circuit.

The entanglement is measured by the Schmidt rank width [2] of the state created by the selected entangler which is defined via sequences of partitions according to a subcubic tree T, where each leaf of T corresponds to a qubit in \(\ket{G}\). Specifically, the Schmidt rank width of a n-qubit state is defined as:

where \(\chi_{e}\) is the log of the Schmidt number of the partition defined by removing an internal edge e∈T, the maximum is taken over all internal edges in T, and the minimum is taken over all subcubic trees with n leaves. Since it is defined via subcubic tree structure the Schmidt rank width of n-qubit graph state is bounded from above by \(\lceil n/3 \rceil\). The Schmidt rank width of \(\ket{G}\) is equal to a width parameter of G – the rank-width \(( rwd(G) )\) of G [2,3] .

The entanglers included in the function library are the hypercube entangler, the two-dimensional entangler, and the grid entangler.

## Hypercube Entangler¶

Function: HypercubeEntangler.

Parameter

`qubit_count`

(int).

### syntax¶

Example 1

```
{
"logic_flow": [{
"function": "HypercubeEntangler",
"function_params": {"qubit_count": 8}
}]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import HypercubeEntangler
hypercube = HypercubeEntangler(qubit_count=8)
model_designer = ModelDesigner()
model_designer.HypercubeEntangler(hypercube)
circuit = model_designer.synthesize()
```

Output circuit:

### Description¶

The HypercubeEntangler function creates a circuit for constructing a graph state \(\ket{G}\) whose
underlying graph is a d dimensional hypercube G = Q_{d} , where d is the largest
possible dimension for the selected number of qubits set by the parameter `qubit_count`

,
connected to the remainder of the qubits.

The d-dimensional hypercube Q_{d} is a graph whose vertices are d-dimensional vectors
with binary coordinates (i_{1},…,i_{d}) where i_{l}={0,1}.
The edges in Q_{d} connect vectors which differ in exactly one coordinate.
A circuit constructing \(\ket{G=Q_{d}}\) includes CZ gates between qubits according to
their binary representation. For example, qubit 0 whose binary representation is (0, …,0)
will be connected by CZ gates to qubits 1, 2, 4, … , 2^{d-1}
whose binary representations are (0,…0,1), (0,…,1,0), … ,(1,0,...,0).

An n-qubit graph state whose underlying graph is Q_{d} (\(n=2^{d}\)) is a highly entangled
state, whose Schmidt rank width is asymptotically close to the maximal possible one.

Specifically, The rank width of \(Q_{d}\), which is equal to the Schmidt rank width of \(\ket{Q_{d}}\), is bounded by:

For n qubits where n= 2^{d} the function will create a circuit that when applied to
the |0⟩^{(⨂n)} state outputs a graph state in the form of d dimensional hypercube
Q_{d}.

For `qubit_count`

of 2^{3} = 8 qubits, as in example 1, the circuit generated by the
function creates the three-dimensional cube Q_{3}.

For \(2^{d} < n < 2^{d+1}\) the HypercubeEntangler will output a circuit connecting each qubit to all its neighbors in a form of an incomplete \(2^{d+1}\) dimensional hypercube.

For 11 qubits the circuit will construct a three-dimensional cube connected to the three additional qubits as follows:

Example 2

```
{
"logic_flow": [{
"function": "HypercubeEntangler",
"function_params": {"qubit_count": 11}
}]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import HypercubeEntangler
hypercube = HypercubeEntangler(qubit_count=11)
model_designer = ModelDesigner()
model_designer.HypercubeEntangler(hypercube)
circuit = model_designer.synthesize()
```

Output circuit:

## Two-dimensional Entangler¶

Function: TwoDimensionalEntangler.

Parameters

`qubit_count`

(int).`schmidt_rank`

(int).

### Syntax¶

Example 1

```
{
"logic_flow": [{
"function": "TwoDimensionalEntangler",
"function_params": {"qubit_count": 6, "schmidt_rank": 2}
}]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import TwoDimensionalEntangler
two_D_grid = TwoDimensionalEntangler(qubit_count=6, schmidt_rank=2)
model_designer = ModelDesigner()
model_designer.TwoDimensionalEntangler(two_D_grid)
circuit = model_designer.synthesize()
```

Output circuit:

### Description¶

The two dimensional entangler function creates a circuit for constructing a graph state \(\ket{G}\) whose underlying graph is a two-dimensional rectangular \(d_{1} \times d_{2}\) grid where \(d_{1} > d_{2}\).

The function constructs a circuit for grid with \(d_{2}\) equal to the `schmidt_rank`

provided that large enough `qubit_count`

was specified. Namely, for `qubit_count`

= \(N\),
`schmidt_rank`

= \(K\), if \(\lfloor N/K \rfloor ≥ K\) then a \(\lfloor N/K \rfloor\) by \(K\) grid
is constructed. Otherwise, a circuit for a rectangular grid is constructed,
where the smaller dimension is \(d_{2} =\lfloor \sqrt N \rfloor\) if
possible, and \(d_{2} =\lfloor \sqrt N \rfloor-1\) if not.

Example 2

For `qubit_count`

= 9 and `schmidt_rank`

= 2 a circuit for constructing a 2 x 4 grid is
constructed.

```
{
"logic_flow": [{
"function": "TwoDimensionalEntangler",
"function_params": {"qubit_count": 9, "schmidt_rank": 2}
}]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import TwoDimensionalEntangler
two_D_grid = TwoDimensionalEntangler(qubit_count=9, schmidt_rank=2)
model_designer = ModelDesigner()
model_designer.TwoDimensionalEntangler(two_D_grid)
circuit = model_designer.synthesize()
```

Output circuit:

Example 3

For `qubit_count`

= 17 and `schmidt_rank`

= 5 a circuit for constructing a 3 x 5 grid is
constructed.

```
{
"logic_flow": [{
"function": "TwoDimensionalEntangler",
"function_params": {"qubit_count": 17, "schmidt_rank": 5}
}]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import TwoDimensionalEntangler
two_D_grid = TwoDimensionalEntangler(qubit_count=17, schmidt_rank=5)
model_designer = ModelDesigner()
model_designer.TwoDimensionalEntangler(two_D_grid)
circuit = model_designer.synthesize()
```

Output circuit:

## Grid Entangler¶

Function: GridEntangler.

Parameters:

`qubit_count`

(int).`schmidt_rank`

(int).`grid_randomization`

Optional (bool).

### Syntax¶

Example 1

```
{
"logic_flow": [{
"function": "GridEntangler",
"function_params": {"qubit_count": 16, "schmidt_rank": 4}
}]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import GridEntangler
grid = GridEntangler(qubit_count=16, schmidt_rank=4)
model_designer = ModelDesigner()
model_designer.GridEntangler(grid)
circuit = model_designer.synthesize()
```

Output circuit:

### Description¶

The grid entangler function creates a circuit for constructing a graph state whose underlying graph is a multidimensional \(d_{1} \times d_{2}\times ... \times d_{n}\) grid, where \(d_{1} \leq d_{2} \leq ...\leq d_{n}\). The grid entangler function attempts to construct a grid whose dimensions obey the following conditions:

`qubit_count`

= \(d_{1} \times d_{2} \times ...\times d_{n}\) and`schmidt_rank`

= \(d_{1} \times d_{2} \times...\times d_{n-1}\), where- \((d_{1}-1) + ...+ (d_{n-1}-1) < d_{n}-1\).

If these conditions cannot be met than a grid with
`qubit_count`

< \(d_{1} \times d_{2}\times...\times d_{n}\), and
\({d_{1} \times...\times d_{n-1}}\) as close as possible to, and
smaller than, the `schmidt_rank`

is constructed.

The optional `grid_randomization`

parameter triggers a randomization of the grid structure. By default,
`grid_randomization`

= True. In the case `grid_randomization`

= False the selected (default) grid structure
has a maximal number of dimensions (n) and minimal
\(d_{1},..., d_{n-1}\) dimensions (and therefore maximal \(d_{n}\)).
For `grid_randomization`

= True, the grid structure is selected randomly out of all grids with
the same products \(d_{1} \times ...\times d_{n}\) and
\(d_{1} \times ...\times d_{n-1}\) as in the default grid, which obey condition 3.

For `qubit_count`

= 12 and `schmidt_rank`

= 4 the generated circuit constructs a 2x2x4 grid as in example 1.

Example 2

For `qubit_count`

= 25, `schmidt_rank`

= 4, and grid_randomisation = false the generated circuit constructs a
2x2x6 grid (note that one qubit remains unconnected to the grid).

```
{
"logic_flow": [
{
"function": "GridEntangler",
"function_params": {
"qubit_count": 25,
"schmidt_rank": 4,
"grid_randomization": false
}
}
]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import GridEntangler
grid = GridEntangler(qubit_count=25, schmidt_rank=4, grid_randomization=False)
model_designer = ModelDesigner()
model_designer.GridEntangler(grid)
circuit = model_designer.synthesize()
```

Output circuit:

Example 3

For `qubit_count`

= 25 and `schmidt_rank`

= 4 (`grid_randomization`

is by default true) one may obtain either
the circuit of the previous example, or the following output circuit constructing a 4x6 grid.

```
{
"logic_flow": [
{
"function": "GridEntangler",
"function_params": {
"qubit_count": 25,
"schmidt_rank": 4
}
}
]
}
```

```
from classiq import ModelDesigner
from classiq.builtin_functions import GridEntangler
grid = GridEntangler(qubit_count=25, schmidt_rank=4)
model_designer = ModelDesigner()
model_designer.GridEntangler(grid)
circuit = model_designer.synthesize()
```

One of the possible output circuits:

## References¶

[1] M. Hein, W. Dur, J. Eisert, R. Raussendorf, M. Van den Nest, H. J. Briegel, "Entanglement in Graph States and its Applications", Phys. Rev. A, 63320645, (2006), arXiv:quant-ph/0602096 (2006).

[2] M. Van den Nest, W. Dur, G. Vidal, H. J. Briegel, "Classical simulation versus universality in measurement-based quantum computation", Phys. Rev. A 75, 012337 (2007).

[3] S.-I. Oum, "Rank-width: Algorithmic and structural results", Lect. Notes Comput. Sci. 3787, 49 (2005)