> ## Documentation Index
> Fetch the complete documentation index at: https://docs.classiq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimizing MCX Gates, Preparing for Future Hardware Today

<Card title="View on GitHub" icon="github" href="https://github.com/Classiq/classiq-library/blob/main/tutorials/basic_tutorials/mcx/mcx.ipynb">
  Open this notebook in GitHub to run it yourself
</Card>

This tutorial describes how to use the Classiq platform to create MCX gates, including one with 14 controls. Then, it demonstrates a much more complex example with 50 control qubits.

## Quantum Resources Are Valuable, yet Limited

Quantum computers offer tantalizing promises to those who can harness their power.

And although today's computers are not quite able to solve real-world problems, those who are able to optimize for the available hardware can reap rewards sooner than those who wait.

The MCX gate is an important quantum gate used in a variety of circuits, such as the Grover operator, logical AND operator, state preparation algorithms, and arithmetic comparators.

The ability to adapt implementations of MCX gates to meet the hardware constraints - limited qubit count, fidelities, gate count, and so on - is not trivial.

## Creating a 14-Control MCX Gate with Classiq

To create an MCX gate with 14 control qubits using Classiq, we first define a quantum function called `my_mcx` whose arguments are an array of qubits (of any size) for `control` and a single qubit argument for the `target`:

```python theme={null}
from math import pi

from classiq import *
```

```python theme={null}

@qfunc
def my_mcx(cntrl: QArray, target: QBit) -> None:
    control(cntrl, lambda: X(target))
```

To create an MCX gate with 14 control qubits, we create a quantum `main` function that executes our `my_mcx` function with 14 qubits allocated to the `control` argument:

```python theme={null}
@qfunc
def main(cntrl: Output[QArray], target: Output[QBit]) -> None:
    allocate(14, cntrl)
    allocate(target)
    my_mcx(cntrl, target)
```

To constrain a circuit to only 20 qubits and optimize for circuit depth, we pass the maximum width and optimization parameter to a `Constraints` object and synthesize our model, create a quantum program, and view it:

```python theme={null}
MAX_WIDTH_1 = 20
constraints_1 = Constraints(
    max_width=MAX_WIDTH_1, optimization_parameter=OptimizationParameter.DEPTH
)
qprog_1 = synthesize(main, constraints=constraints_1)
show(qprog_1)
```

<Info>
  **Output:**

  ```

  Quantum program link: https://platform.classiq.io/circuit/3Hok9FDaBHGhpjNnhS0BkkWdeW1
    

  ```
</Info>

Additionally, to get the transpiled circuit from our `qprog` object and print its depth:

```python theme={null}
print(f"Synthesized MCX depth is {get_transpiled_circuit_metrics(qprog_1).depth}")
```

<Info>
  **Output:**

  ```

  Synthesized MCX depth is 81
    

  ```
</Info>

## Optimizing MCX for Every Occasion

Classiq automatically optimizes the quantum circuit and each MCX gate to a plethora of possible situations. To characterize each setting we pass our constraints and preferences to the synthesis request using the `Constraints` and `Preferences` objects.

#

## For Different Hardware

```python theme={null}
MAX_WIDTH_2 = 21

constraints_2 = Constraints(
    max_width=MAX_WIDTH_2, optimization_parameter=OptimizationParameter.DEPTH
)
preferences_2 = Preferences(
    backend_service_provider="IBM Quantum", backend_name="ibm_boston"
)


qprog_2 = synthesize(main, constraints=constraints_2, preferences=preferences_2)
print(f"Synthesized MCX depth is {get_transpiled_circuit_metrics(qprog_2).depth}")
show(qprog_2)
```

<Info>
  **Output:**

  ```

  Synthesized MCX depth is 202
    Quantum program link: https://platform.classiq.io/circuit/3Hok9r3scdPaLk0aJZiKSU7sKsW
    

  ```
</Info>

#

## For CX Gates

```python theme={null}
MAX_WIDTH_3 = 17

constraints_3 = Constraints(max_width=MAX_WIDTH_3, optimization_parameter="cx")
preferences_3 = Preferences(
    custom_hardware_settings=CustomHardwareSettings(basis_gates=["cx", "u"])
)

qprog_3 = synthesize(main, constraints=constraints_3, preferences=preferences_3)
print(
    f"Synthesized MCX cx-count is {get_transpiled_circuit_metrics(qprog_3).count_ops['cx']}"
)
show(qprog_3)
```

<Info>
  **Output:**

  ```

  Synthesized MCX cx-count is 90
    Quantum program link: https://platform.classiq.io/circuit/3HokAOpsBFNYUoa0nbxrCdALv4D
    

  ```
</Info>

## Beyond 14 Controls

The power of the Classiq synthesis engine is far greater than creating optimized, 14-control MCX gates in an instant.

For example, the following code creates an MCX gate with 50 control qubits:

```python theme={null}
@qfunc
def main(cntrl: Output[QArray], target: Output[QBit]) -> None:
    allocate(50, cntrl)
    allocate(target)
    my_mcx(cntrl, target)


constraints_4 = Constraints(optimization_parameter="depth")
preferences_4 = Preferences(optimization_level=0)
qprog_4 = synthesize(main, constraints=constraints_4, preferences=preferences_4)
show(qprog_4)
```

<Info>
  **Output:**

  ```

  Quantum program link: https://platform.classiq.io/circuit/3HokAqmLFsI7fnLkNIOo6xMKb1E
    

  ```
</Info>

<img src="https://mintcdn.com/classiq/fTuEJBV0Zi8fV6NU/explore/tutorials/basic_tutorials/mcx/mcx_50_control_circuit.png?fit=max&auto=format&n=fTuEJBV0Zi8fV6NU&q=85&s=906e2c64607b2c72515a667d9b6ad07f" alt="Synthesized 50-control MCX circuit" width="2530" height="1485" data-path="explore/tutorials/basic_tutorials/mcx/mcx_50_control_circuit.png" />
