Generazione Ansatz
qiskit_addon_aqc_tensor.ansatz_generation
Strumenti per la generazione di circuiti ansatz.
AnsatzBlock | Blocco Ansatz. |
OneQubitAnsatzBlock | Blocco di ansatz a un qubit. |
TwoQubitAnsatzBlock | Blocco di ansatz a due qubit. |
ZXZ | Blocco di ansatz a un qubit basato sulla decomposizione ZXZ. |
KAK | Blocco di ansatz a due qubit basato sulla decomposizione KAK. |
generate_ansatz_from_circuit
generate_ansatz_from_circuit(qc, /, *, qubits_initially_zero=False, parameter_name='theta')
Generare un ansatz dalla struttura di connettività a due qubit di un circuito.
Per la motivazione si veda il materiale esplicativo.
Parametri
- qc (
QuantumCircuit) – Un circuito, che si presume unitario. Le barriere vengono ignorate. - qubits_initially_zero (
bool) – SeTrue, la prima rotazione Z su ogni qubit è fissata a zero perché tale rotazione non ha effetto sullo stato . - parameter_name (
str) – Nome per i parametriParameterVectorche rappresenta i parametri liberi nel circuito di ansatz restituito.
Tipo di restituzione
tuple[QuantumCircuit, list[float]]
Risultati
(ansatz, parameter_values) tale che ansatz.assign_parameters(parameter_values) è equivalente a qc fino a una fase globale.
Esempio:
Si consideri il seguente circuito come esempio:
from qiskit import QuantumCircuit
qc = QuantumCircuit(6)
qc.rx(0.4, 0)
qc.ryy(0.2, 2, 3)
qc.h(2)
qc.rz(0.1, 2)
qc.rxx(0.3, 0, 1)
qc.rzz(0.3, 0, 1)
qc.cx(2, 1)
qc.s(1)
qc.h(4)
qc.draw("mpl")Se il circuito di cui sopra viene passato a generate_ansatz_from_circuit()restituirà un'ansatz con rotazioni KAK a due qubit parametrizzate nelle stesse posizioni dell'input:
from qiskit_addon_aqc_tensor import generate_ansatz_from_circuit
ansatz, initial_params = generate_ansatz_from_circuit(
qc, qubits_initially_zero=True, parameter_name="x"
)
ansatz.draw("mpl")Si noti che nell'ansatz generato, tutte le porte consecutive a un solo bit sono collassate nello stesso blocco ZXZ e tutte le porte consecutive a due bit sono collassate in un unico blocco KAK, fino alle rotazioni a un solo bit.
Inoltre, la funzione generate_ansatz_from_circuit() fornisce parametri che, se legati all'ansatz, daranno come risultato un circuito equivalente a quello originale, fino a una fase globale:
ansatz.assign_parameters(initial_params).draw("mpl")Un circuito 1D Trotter porta a un risultato simile, con la sua caratteristica struttura in mattoni:
from rustworkx.generators import path_graph
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit, generate_xyz_hamiltonian
hamiltonian = generate_xyz_hamiltonian(
path_graph(6),
coupling_constants=(0.0, 0.0, 1.0),
ext_magnetic_field=(0.4, 0.0, 0.0),
)
good_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=2),
time=1.0,
)
good_circuit.draw("mpl", initial_state=True)from qiskit_addon_aqc_tensor import generate_ansatz_from_circuit
ansatz, initial_params = generate_ansatz_from_circuit(
good_circuit, qubits_initially_zero=True, parameter_name="x"
)
ansatz.assign_parameters(initial_params).draw("mpl", initial_state=True)parametrize_circuit
parametrize_circuit(qc, /, *, parameter_name='theta')
Creare una versione parametrizzata di un circuito.
Dato un circuito quantistico, costruisce un altro circuito quantistico identico, tranne che per il fatto che le porte con parametri numerici sono sostituite da porte (dello stesso tipo) con parametri liberi. Il nuovo circuito viene restituito insieme a un elenco contenente i valori originali dei parametri.
Parametri
- qc (
QuantumCircuit) – Il circuito quantistico da parametrizzare. - parameter_name (
str) – Nome per i parametriParameterVectorche rappresenta i parametri liberi nel circuito di ansatz restituito.
Tipo di restituzione
tuple[QuantumCircuit, list[float | None]]
Risultati
(ansatz, parameter_values) in modo tale che ansatz.assign_parameters(parameter_values) sia identico a qc , purché qc non contenga già parametri. Se qc aveva già dei parametri, allora parameter_values conterrà None alle voci corrispondenti a tali parametri.
Esempio:
Si consideri il seguente circuito come esempio:
from qiskit import QuantumCircuit
qc = QuantumCircuit(6)
qc.rx(0.4, 0)
qc.ryy(0.2, 2, 3)
qc.h(2)
qc.rz(0.1, 2)
qc.rxx(0.3, 0, 1)
qc.rzz(0.3, 0, 1)
qc.cx(2, 1)
qc.s(1)
qc.h(4)
qc.draw("mpl")Se il circuito di cui sopra viene passato a parametrize_circuit()restituirà un'ansatz ottenuta da questo circuito sostituendo i parametri numerici con parametri liberi:
from qiskit_addon_aqc_tensor import parametrize_circuit
ansatz, initial_params = parametrize_circuit(qc)
ansatz.draw("mpl")Inoltre, la parametrize_circuit() fornisce parametri che, se vincolati all'ansatz, daranno come risultato un circuito identico a quello originale:
ansatz.assign_parameters(initial_params).draw("mpl")Se il circuito originale conteneva già dei parametri, i valori dei parametri restituiti conterranno None alle voci corrispondenti a tali parametri e il codice precedente non funzionerà. L'esempio seguente mostra come recuperare il circuito originale in questo caso.
from qiskit.circuit import Parameter
qc = QuantumCircuit(3)
alpha1 = Parameter("alpha1")
alpha2 = Parameter("alpha2")
qc.ry(alpha1, [0])
qc.rz(0.1, [0])
qc.ry(alpha2, [1])
qc.rz(alpha1, [1])
qc.ry(0.2, [2])
qc.rz(0.3, [2])
ansatz, initial_params = parametrize_circuit(qc)
ansatz.assign_parameters(
{
param: val
for param, val in zip(ansatz.parameters, initial_params)
if val is not None
},
inplace=True,
)
ansatz.draw("mpl")