Quantum circuit simulator with sparse and dense implementations
Project description
quipy
quipy is a quantum circuit simulator with sparse and dense density matrix implementations.
quipy.dense
The dense simulation consists of direct numpy matrix manipulation, such as applying operators to the density matrix $U \rho U^\dagger$, taking the trace $\text{Tr}(\rho)$, etc.
This model of simulation becomes inefficient when simulating large systems with a few matrix entries. For example, a 10 qubit system has a density matrix of size $1024 \times 1024$, which is $1048576$ elements! For a state, such as $\frac{1}{2}\ket{0}^{\otimes 10} \bra{0}^{\otimes 10} + \frac{1}{2} \ket{1}^{\otimes 10}\bra{1}^{\otimes 10}$, this type of simulation is overkill.
quipy.sparse
The sparse simulation consists of term manipulation. Internally, we treat the density matrix entries as a list of terms with coefficients, just like the mathematical definition of a density matrix:
$$ \rho = \sum_i p_i \ket{\psi_i} \bra{\psi_i}. $$
Instead of directly multiplying operators with the density matrix, we use the fact that they're linear, which means they can act on each term separately:
$$ U \rho U^\dagger = \sum_i p_i U\ket{\psi_i} \bra{\psi_i}U^\dagger $$
This type of simulation, as the name suggests, is preferred for sparse systems—systems with a small number of entries.
The state $\frac{1}{2}\ket{0}^{\otimes 10} \bra{0}^{\otimes 10} + \frac{1}{2} \ket{1}^{\otimes 10}\bra{1}^{\otimes 10}$ in this simulation just requires two entries in the term list, compared to the $1048576$ elements required in the dense simulation.
quipy.ops
This is an auxiliary module which holds definitions for common quantum gates, such as $I, X, Y, Z, H, S, T, R_x, R_y,$ and $R_z$.
Examples
The library supports latex representation of the current state, which is useful in a jupyter notebook. Below is an example.
import quipy.sparse as qis
state = qis.State(num_qubits=2)
state
$$\rho = |00\rangle\langle 00|$$
Below are sparse and dense examples of the Bell circuit.
import quipy.sparse as qis
import quipy as qi
# Bell circuit
circuit = qis.Circuit(num_qubits=2)
circuit.add_gate(qi.ops.H, qubit=0)
circuit.CNOT(control_qubit=0, target_qubit=1)
# Running the circuit
state = qis.State(num_qubits=2)
final = circuit.run(initial_state=state)
final
$$\rho = \frac{1}{2}|00\rangle\langle 00| + \frac{1}{2}|00\rangle\langle 11| + \frac{1}{2}|11\rangle\langle 00| + \frac{1}{2}|11\rangle\langle 11|$$
import quipy.dense as qis
import quipy as qi
# Bell circuit
circuit = qis.Circuit(num_qubits=2)
circuit.add_gate(qi.ops.H, qubit=0)
circuit.CNOT(control_qubit=0, target_qubit=1)
# Running the circuit
state = qis.State(num_qubits=2)
final = circuit.run(initial_state=state)
final
$$\rho = \frac{1}{2}|00\rangle\langle 00| + \frac{1}{2}|00\rangle\langle 11| + \frac{1}{2}|11\rangle\langle 00| + \frac{1}{2}|11\rangle\langle 11|$$
Below is an implementation of the repetition error correcting circuit using the sparse simulator.
import quipy.sparse as qis
import quipy as qi
from IPython.display import HTML
circuit = qis.Circuit(num_qubits=5)
# Encoding
circuit.CNOT(control_qubit=0, target_qubit=1)
circuit.CNOT(control_qubit=0, target_qubit=2)
# Noise happens here
# Emulate a fake bitflip
circuit.add_gate(qi.ops.X, qubit=1)
circuit.add_callback(lambda state: display(HTML("State after a bit-flip error:"), state))
# Correction
def correct(state: qis.State, results):
match results:
case [1, 0]:
state.apply_gate(qi.ops.X, qubit=0)
display(HTML("Corrected qubit 0"))
case [1, 1]:
state.apply_gate(qi.ops.X, qubit=1)
display(HTML("Corrected qubit 1"))
case [0, 1]:
state.apply_gate(qi.ops.X, qubit=2)
display(HTML("Corrected qubit 2"))
circuit.CNOT(control_qubit=0, target_qubit=3)
circuit.CNOT(control_qubit=1, target_qubit=3)
circuit.CNOT(control_qubit=1, target_qubit=4)
circuit.CNOT(control_qubit=2, target_qubit=4)
circuit.measuring_device(qubits=[3, 4], callback=correct)
# Run
state = qis.State(num_qubits=5)
display(state)
final = circuit.run(initial_state=state)
final.latex_symbol = r"\rho^\prime"
display(final)
$$\rho = |00000\rangle\langle 00000|$$
State after a bit-flip error:
$$\rho = |01000\rangle\langle 01000|$$
Corrected qubit 1
$$\rho^\prime = |00011\rangle\langle 00011|$$
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quipy-0.1.1.tar.gz.
File metadata
- Download URL: quipy-0.1.1.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91918811d0c5789891529d75796fba8d3d7611442d8d77121db63a558664cbcf
|
|
| MD5 |
53849594cf21a522bf3dbc4dde4c4266
|
|
| BLAKE2b-256 |
8a6280ce0aa8bcd0d0637167b2fd7dcf928f2c511ad5248284a322cc7d2233e9
|
File details
Details for the file quipy-0.1.1-py3-none-any.whl.
File metadata
- Download URL: quipy-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b090ea6f409ccee7c1538c6c312fe9322b82e55a9891705e863ef1dde703e3c1
|
|
| MD5 |
976039d4f4db7819f1bd5f3f3aecc1e9
|
|
| BLAKE2b-256 |
fa2c3314f23e8f6eef8a35beee6cd398c578c79fbe95d19128dcc2260e2074aa
|