Sintetizzare operazioni unitarie
Versioni dei pacchetti
Il codice in questa pagina è stato sviluppato utilizzando i seguenti requisiti. Si consiglia di usare queste versioni o versioni più recenti.
qiskit[all]~=2.5.2
Un'operazione unitaria descrive una trasformazione che conserva la norma di un sistema quantistico. Per qubit, questa trasformazione è descritta da una matrice complessa di dimensione il cui aggiunto è uguale all'inverso, ovvero .
La sintesi di operazioni unitarie specifiche in un insieme di gate quantistici è un'attività fondamentale, utilizzata ad esempio nella progettazione e nell'applicazione di algoritmi quantistici o nella compilazione di circuiti quantistici.
Sebbene una sintesi efficiente sia possibile per certe classi di unitarie — come quelle composte da gate di Clifford o con una struttura a prodotto tensoriale — la maggior parte delle unitarie non rientra in queste categorie. Per le matrici unitarie generali, la sintesi è un'operazione complessa i cui costi computazionali crescono esponenzialmente con il numero di qubit. Pertanto, se conosci una decomposizione efficiente per l'unitaria che vuoi implementare, è probabile che sia migliore di una sintesi generica.
Se non è disponibile alcuna decomposizione, il Qiskit SDK ti fornisce gli strumenti per trovarne una. Tieni però presente che questo genera generalmente circuiti profondi che potrebbero non essere adatti all'esecuzione su computer quantistici rumorosi.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit import QuantumCircuit
U = 0.5 * np.array(
[[1, 1, 1, 1], [-1, 1, -1, 1], [-1, -1, 1, 1], [-1, 1, 1, -1]]
)
circuit = QuantumCircuit(2)
circuit.unitary(U, circuit.qubits)
<qiskit.circuit.instructionset.InstructionSet at 0x1058da0b0>
Ri-sintesi per l'ottimizzazione del circuito
A volte è vantaggioso ri-sintetizzare una lunga serie di gate a uno e due qubit, se è possibile ridurne la lunghezza. Ad esempio, il circuito seguente utilizza tre gate a due qubit.
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qreg_q = QuantumRegister(2, "q")
creg_c = ClassicalRegister(4, "c")
circuit = QuantumCircuit(qreg_q, creg_c)
circuit.h(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.sx(qreg_q[1])
circuit.cz(qreg_q[0], qreg_q[1])
circuit.x(qreg_q[1])
circuit.x(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.h(qreg_q[0])
circuit.draw("mpl")
Tuttavia, dopo la ri-sintesi con il codice seguente, è sufficiente un singolo gate CX. (Qui usiamo il metodo QuantumCircuit.decompose() per visualizzare meglio i gate usati nella ri-sintesi dell'unitaria.)
from qiskit.quantum_info import Operator
# compute unitary matrix of circuit
U = Operator(circuit)
# re-synthesize
better_circuit = QuantumCircuit(2)
better_circuit.unitary(U, range(2))
better_circuit.decompose().draw()
global phase: 15π/8
┌───────────────┐ ┌────────────────┐
q_0: ┤ U(π/2,π/2,-π) ├───■──┤ U(π/2,-π,-π/2) ├
├───────────────┴┐┌─┴─┐├───────────────┬┘
q_1: ┤ U(3π/4,π/2,-π) ├┤ X ├┤ U(π/2,π/4,-π) ├─
└────────────────┘└───┘└───────────────┘
La funzione transpile di Qiskit esegue automaticamente questa ri-sintesi per un livello di ottimizzazione sufficientemente alto.
Passi successivi
- Guarda un esempio di decomposizione di circuiti nel tutorial Algoritmo di Grover.
- Per ulteriori informazioni sul transpiler di Qiskit, visita la sezione Transpile.