# Circuits

The `Circuit`

struct is used to represent a gate-based quantum computation on qubits. `Circuit`

s can be built up iteratively by applying them as functors to operations like so:

```
julia> c = Circuit();
julia> c(H, Qubit(0));
julia> α = FreeParameter(:alpha);
julia> c(Rx, Qubit(1), α);
julia> c(Probability); # measures probability on all qubits
```

This functor syntax can also be used to set the value of free parameters:

```
julia> α = FreeParameter(:alpha);
julia> θ = FreeParameter(:theta);
julia> circ = Circuit([(H, 0), (Rx, 1, α), (Ry, 0, θ), (Probability,)]);
julia> new_circ = circ(theta=2.0, alpha=1.0);
julia> new_circ2 = circ(0.5); # sets the value of all FreeParameters to 0.5
```

`Braket.Circuit`

— Type`Circuit`

A representation of a quantum circuit that contains the instructions to be performed on a quantum device and the requested result types.

See:

- Gates for all of the supported gates.
- Noises for all of the supported noise operations.
- Compiler Directives for all of the supported compiler directives.
- Results for all of the supported result types.

`Braket.Circuit`

— Method`Circuit()`

Construct an empty `Circuit`

.

`Braket.Circuit`

— Method`Circuit(m::Moments, ixs::Vector, rts::Vector{Result}, bri::Vector)`

Construct a `Circuit`

from a set of `Moments`

, a vector of `Instruction`

s, a vector of `Result`

s, and a vector of basis rotation instructions.

`Braket.Circuit`

— Method`Circuit(v)`

Construct a `Circuit`

from a `Vector`

-like `v`

containing tuples of:

- a
`Gate`

,`Noise`

, or`Result`

- the target qubits on which to apply the operator
- any construction arguments to the operator, e.g. an angle or
`Observable`

**Examples**

```
julia> v = [(H, collect(0:10)), (Rx, 1, 0.2), (BitFlip, 0, 0.1)];
julia> Circuit(v);
```

`Braket.Qubit`

— Type`Qubit <: Integer`

Wrapper `struct`

representing a qubit.

**Examples**

```
julia> q = Qubit(0)
Qubit(0)
julia> q == 0
true
```

`Braket.QubitSet`

— Type`QubitSet`

An `OrderedSet`

-like object which represents the qubits a `Circuit`

, `Instruction`

, or `Result`

acts on and their ordering. Elements may be `Int`

s or `Qubit`

s.

**Examples**

```
julia> QubitSet(1, Qubit(0))
QubitSet with 2 elements:
1
Qubit(0)
julia> QubitSet([2, 1])
QubitSet with 2 elements:
2
1
julia> QubitSet()
QubitSet()
julia> QubitSet(QubitSet(5, 1))
QubitSet with 2 elements:
5
1
```

`Braket.Operator`

— Type`Operator`

Abstract type representing operations that can be applied to a `Circuit`

. Subtypes include `Gate`

, `Noise`

, `Observable`

, and `CompilerDirective`

.

`Braket.QuantumOperator`

— Type`Braket.FreeParameter`

— Type`Braket.depth`

— Function`depth(c::Circuit)`

Returns the number of moments in `c`

. Also known as the "parallel gate depth".

**Examples**

```
julia> c = Circuit();
julia> H(c, 0);
julia> CNot(c, 0, 1);
julia> depth(c)
2
```

`Braket.qubits`

— Function`qubits(c::Circuit) -> QubitSet`

Returns a `QubitSet`

containing all qubits that `c`

is defined on.

**Examples**

```
julia> c = Circuit();
julia> H(c, 0);
julia> CNot(c, 0, 1);
julia> qubits(c)
QubitSet with 2 elements:
0
1
```

`Braket.qubit_count`

— Function`qubit_count(c::Circuit) -> Int`

Returns the number of qubits that `c`

is defined on.

**Examples**

```
julia> c = Circuit();
julia> H(c, 0);
julia> CNot(c, 0, 1);
julia> qubit_count(c)
2
```

`Braket.measure`

— Function`measure(c::Circuit, target_qubits) -> Circuit`

Add a `Measure`

operator to `c`

, ensuring only the targeted qubits are measured. A `Measure`

operation can **only** be applied if the circuit does **not** contain any result types. If `c`

has no qubits defined, or `target_qubits`

are not within the qubit range of `c`

, an `ArgumentError`

is raised. If the circuit `c`

contains any result types, or any of the target qubits are already measured, an `ErrorException`

is raised.

**Examples**

```
julia> circ = Circuit([(H, 0), (CNot, 0, 1)]);
julia> circ = measure(circ, 0);
julia> circ.instructions
3-element Vector{Braket.Instruction}:
Braket.Instruction{H}(H(), QubitSet(0))
Braket.Instruction{CNot}(CNot(), QubitSet(0, 1))
Braket.Instruction{Measure}(Measure(0), QubitSet(0))
julia> circ = Circuit([(H, 0), (CNot, 0, 1), (StateVector,)]);
julia> circ = measure(circ, 0);
ERROR: a circuit cannot contain both measure instructions and result types.
[...]
julia> circ = Circuit([(H, 0), (CNot, 0, 1)]);
julia> circ = measure(circ, [0, 1, 0]);
ERROR: cannot repeat qubit(s) in the same measurement.
[...]
```

`Braket.Measure`

— Type`Measure(index) <: QuantumOperator`

Represents a measurement operation on targeted qubit, stored in the classical register at `index`

.

## Output to IR

`Braket.jl`

provides several functions to transform a `Circuit`

into IR which will be transmitted to Amazon managed QPUs or simulators. Currently, two output formats supported are OpenQASM, and JAQCD (an Amazon Braket native IR). You can control how IR translation is done through the global variable `IRType`

and, if using OpenQASM, `OpenQASMSerializationProperties`

.

`Braket.Instruction`

— Type```
Instruction
Instruction(o::Operator, target)
```

Represents a single operation applied to a `Circuit`

. Contains an `operator`

, which may be any subtype of `Operator`

, and a `target`

set of qubits to which the `operator`

is applied.

**Examples**

```
julia> Braket.Instruction(H(), 1)
Braket.Instruction{H}(H(), QubitSet(1))
julia> Braket.Instruction(CNot(), [1, Qubit(4)])
Braket.Instruction{CNot}(CNot(), QubitSet(1, Qubit(4)))
julia> Braket.Instruction(StartVerbatimBox(), QubitSet())
Braket.Instruction{StartVerbatimBox}(StartVerbatimBox(), QubitSet())
```

`Braket.ir`

— Function`ir(c::Circuit; serialization_properties::SerializationProperties=OpenQASMSerializationProperties())`

Convert a `Circuit`

into IR that can be consumed by the Amazon Braket service, whether local simulators, on-demand simulators, or QPUs. The IR format to convert to by default is controlled by the global variable `IRType`

, which can be modified. Currently `:JAQCD`

and `:OpenQASM`

are supported for `Circuit`

s. If writing to `OpenQASM`

IR, optional `OpenQASMSerializationProperties`

may be specified.

`ir(ahs::AnalogHamiltonianSimulation)`

Generate IR from an `AnalogHamiltonianSimulation`

which can be run on a neutral atom simulator or quantum device.

`Braket.IRType`

— Constant`IRType`

A `Ref{Symbol}`

which records which IR output format to use by default. Currently, two formats are supported:

`:JAQCD`

, the Amazon Braket IR`:OpenQASM`

, the OpenQASM3 representation

By default, `IRType`

is initialized to use `:OpenQASM`

, although this may change in the future. The current default value can be checked by calling `IRType[]`

. To change the default IR format, set `IRType[]`

.

**Examples**

```
julia> IRType[]
:OpenQASM
julia> IRType[] = :JAQCD;
julia> IRType[]
:JAQCD
julia> IRType[] = :OpenQASM;
```

`Braket.OpenQASMSerializationProperties`

— Type`OpenQASMSerializationProperties(qubit_reference_type=VIRTUAL)`

Contains information about how to serialize qubits when outputting to OpenQASM IR. The `qubit_reference_type`

argument may be one of `VIRTUAL`

or `PHYSICAL`

.