Qiskit basics
=============

```
# Import Qiskit
from qiskit import QuantumCircuit, transpile, QuantumRegister, ClassicalRegister
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram, plot_state_city
```

Quantum circuits
----------------

Create and display a quantum circuit:

```
circ = QuantumCircuit(numQubits[, numBits])
circ.draw(output="mpl")
```

manually specify registers so they have names that can be referred to later (otherwise they will just be numbered):

```
qubit1 = QuantumRegister(1, "Q")
bit1 = ClassicalRegister(1, "C")
circ = QuantumCircuit(qubit1, bit1)
qubit2 = QuantumRegister(1, "Q2")
circ.add_register(qubit2)
```

compose circuits (need to assign result to variable):

```
jointCirc = circ1.compose(circ2[, listOfQubits])
```

Quantum gates acting on named or numbered qubits:

```
circ.h(qubitIndex)
circ.cx(control, target)
circ.s(qubitIndex)
circ.t(qubitIndex)
circ.p(phase, qubitIndex)
circ.toffoli(control1, control2, target)
circ.z(qubitIndex)
circ.x(qubitIndex)
```

insert a 'barrier' to tell Qiskit certain parts of a circuit are meant to stay separate (this is purely a Qiskit component, it's not used in quantum circuits otherwise):

```
circ.barrier()
```

Classical control (e.g. for Bob's operations in quantum teleportation):

```
with circ.if_test((classicalReg, value)):
    ...
```

Measurements:

```
circ.measure(qubit, outcomeRegister)
circ.measure_all()
```

Simulate a circuit:

```
# Run and get counts
result = AerSimulator().run(circ).result()
statistics = result.get_counts(circ)
plot_histogram(counts)
```

Get marginal statistics for some of the classical registers only:

```
filtered_statistics = marginal_distribution(statistics, listOfIndices)
display(plot_histogram(filtered_statistics))
```
