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

# Execution Tutorial - Part 1

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

This tutorial covers the basics of executing a quantum program using Classiq directly through the Python SDK. It is also possible to use the [Classiq Platform](https://platform.classiq.io) to execute quantum algorithms.

For this, we will start by synthesizing the following example from the [synthesis tutorial](https://docs.classiq.io/latest/explore/tutorials/basic_tutorials/the_classiq_tutorial/synthesis_tutorial/):

```python theme={null}
from classiq import *


@qfunc
def main(x: Output[QNum[3]], y: Output[QNum]) -> None:
    allocate(x)
    hadamard_transform(x)
    y |= x**2 + 1


qprog = synthesize(main)
show(qprog)
```

<Info>
  **Output:**

  ```

  Quantum program link: https://platform.classiq.io/circuit/30HuOnn0LwUGqLIKMlUETImaIfc
    

  ```
</Info>

This quantum program evaluates the function $y(x) = x^2 + 1$, for all integers $x \in [0,7]$. To execute a quantum program and save its results in the Python SDK, create an `ExecutionSession`. To sample the states using this object, one can use `sample`:

```python theme={null}
with ExecutionSession(qprog) as es:
    results = es.sample()
```

<Info>
  **Output:**

  ```
  gio: https://platform.classiq.io/circuit/30HuOnn0LwUGqLIKMlUETImaIfc?login=True&version=0.86.1: Operation not supported
    

  ```
</Info>

The information from the outputs of the quantum program can be obtained in the form of a dataframe using the `dataframe` attribute:

```python theme={null}
results.dataframe
```

|   | x | y  | count | probability | bitstring |
| - | - | -- | ----- | ----------- | --------- |
| 0 | 1 | 2  | 285   | 0.139160    | 000010001 |
| 1 | 7 | 50 | 262   | 0.127930    | 110010111 |
| 2 | 5 | 26 | 260   | 0.126953    | 011010101 |
| 3 | 4 | 17 | 254   | 0.124023    | 010001100 |
| 4 | 2 | 5  | 253   | 0.123535    | 000101010 |
| 5 | 6 | 37 | 251   | 0.122559    | 100101110 |
| 6 | 3 | 10 | 249   | 0.121582    | 001010011 |
| 7 | 0 | 1  | 234   | 0.114258    | 000001000 |

The information displayed in the dataframe is:

* `counts` shows the number of times each state was measured.
* `bitstring` is the bitstring that represents each state measured.
* `x` and `y` are the numerical representation of the states associated with the measurement.
* `probability` is the probability associated with each measured state.

By default, the number of executions of the quantum program is $2048$.

This quantity, called the number of shots, can be modified using `ExecutionPreferences`.

For instance, if we want to execute the same circuit with $10{,}000$ shots:

```python theme={null}
prefs_more_shots = ExecutionPreferences(num_shots=10000)

with ExecutionSession(qprog, execution_preferences=prefs_more_shots) as es:
    results_more_shots = es.sample()
```

The number of counts for each state will grow proportionally with the number of shots:

```python theme={null}
results_more_shots.dataframe
```

|   | x | y  | count | probability | bitstring |
| - | - | -- | ----- | ----------- | --------- |
| 0 | 7 | 50 | 1274  | 0.1274      | 110010111 |
| 1 | 2 | 5  | 1273  | 0.1273      | 000101010 |
| 2 | 1 | 2  | 1267  | 0.1267      | 000010001 |
| 3 | 6 | 37 | 1266  | 0.1266      | 100101110 |
| 4 | 4 | 17 | 1254  | 0.1254      | 010001100 |
| 5 | 5 | 26 | 1226  | 0.1226      | 011010101 |
| 6 | 3 | 10 | 1224  | 0.1224      | 001010011 |
| 7 | 0 | 1  | 1216  | 0.1216      | 000001000 |

## Backend selection

The backend of an execution is the hardware or simulator where the quantum program is executed. To select a specific backend, it is necessary to use its correct Backend Preferences.

Check the different [Cloud Providers](https://docs.classiq.io/latest/user-guide/execution/cloud-providers/) and their backend preferences for execution.

In this section, we will explore two different examples for clarification:

#

## First example: Execution using the state vector simulator from Classiq

A state vector simulator outputs the amplitudes of a quantum program. On real hardware, obtaining these amplitudes requires quantum tomography — the process of measuring in different bases to reconstruct the output state.

Since Classiq provides its own state vector simulator backend, we will use `ClassiqBackendPreferences` to define it as the state vector simulator.

This information is provided on the [Cloud Providers page](https://docs.classiq.io/latest/user-guide/execution/cloud-providers/).

To define the quantum program's execution preferences, use `execution_preferences` under `ExecutionSession`. In this example, we will perform a simulation with `num_shots=1` since the state vector simulator performs an exact simulation of the quantum program.

If no backend is defined in the preferences, then the [Classiq simulator](https://docs.classiq.io/latest/user-guide/execution/cloud-providers/classiq-backends/) is selected by default.

```python theme={null}
backend_preferences = ClassiqBackendPreferences(
    backend_name="simulator_statevector"
)  # Always check the Cloud Providers to correctly define the backend.

execution_preferences = ExecutionPreferences(
    num_shots=1, backend_preferences=backend_preferences
)
```

Now, execute the quantum program using `execute`.

```python theme={null}
with ExecutionSession(qprog, execution_preferences=execution_preferences) as es:
    results_statevector = es.sample()
```

The outputs of the quantum program can be displayed using the `dataframe` property:

```python theme={null}
results_statevector.dataframe.head()
```

|   | x | y  | amplitude                   | probability  | bitstring |
| - | - | -- | --------------------------- | ------------ | --------- |
| 0 | 7 | 18 | 3.923208e-15+2.775558e- 17j | 1.539233e-29 | 010010111 |
| 1 | 0 | 33 | 3.014272e-15+0.000000e+ 00j | 9.085836e-30 | 100001000 |
| 2 | 4 | 49 | 1.538630e-15-5.551115e- 17j | 2.370465e-30 | 110001100 |
| 3 | 3 | 42 | 1.303117e-15+2.775558e- 17j | 1.698883e-30 | 101010011 |
| 4 | 5 | 58 | 1.185360e-15+1.387779e- 16j | 1.424337e-30 | 111010101 |

The outputs from the execution obtained via statevector simulator will differ from the default simulator:

* `state_vector` will output a `dict` containing the bitstrings followed by its numerically evaluated amplitudes.
* `parsed_state_vector` will output a `list` of `SimulatedState`, each containing the values of `x` and `y` followed by its bitstrings and its numerically evaluated amplitudes.
