Generación de Ansatz
qiskit_addon_aqc_tensor.ansatz_generation
Herramientas para generar circuitos ansatz.
AnsatzBlock | Bloque Ansatz. |
OneQubitAnsatzBlock | Bloque ansatz de un qubit. |
TwoQubitAnsatzBlock | Bloque ansatz de dos qubits. |
ZXZ | Bloque ansatz de un qubit basado en la descomposición ZXZ. |
KAK | Bloque ansatz de dos qubits basado en la descomposición KAK. |
generate_ansatz_from_circuit
generate_ansatz_from_circuit(qc, /, *, qubits_initially_zero=False, parameter_name='theta')
Generar un ansatz a partir de la estructura de conectividad de dos qubits de un circuito.
Véase la motivación en el material explicativo.
Parámetros
- qc (
QuantumCircuit) – Un circuito, que se supone unitario. Se ignoran las barreras. - qubits_initially_zero (
bool) – SiTrue, la primera rotación Z en cada qubit se fija en cero porque dicha rotación no tiene ningún efecto sobre el estado . - parameter_name (
str) – Nombre para elParameterVectorque representa los parámetros libres en el circuito ansatz devuelto.
Tipo de retorno
tuple[QuantumCircuit, list[float]]
Devuelve
(ansatz, parameter_values) tal que ansatz.assign_parameters(parameter_values) es equivalente a qc hasta una fase global.
Ejemplo:
Considere el siguiente circuito como ejemplo:
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")Si el circuito anterior se pasa a generate_ansatz_from_circuit()devolverá un ansatz con rotaciones KAK parametrizadas de dos qubits en las mismas posiciones que la entrada:
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")Nótese que en el ansatz generado, todas las puertas consecutivas de un solo qubit se colapsan en el mismo bloque ZXZ, y todas las puertas consecutivas de dos qubits se colapsan en un único bloque KAK, hasta rotaciones de un solo qubit.
Además, la función generate_ansatz_from_circuit() proporciona parámetros que, cuando se vinculan al ansatz, darán como resultado un circuito equivalente al original, hasta una fase global:
ansatz.assign_parameters(initial_params).draw("mpl")Un circuito 1D Trotter conduce a un resultado similar, con su característica estructura de ladrillo:
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')
Crear una versión parametrizada de un circuito.
Dado un circuito cuántico, construye otro circuito cuántico que sea idéntico excepto en que las puertas con parámetros numéricos se sustituyen por puertas (del mismo tipo) con parámetros libres. El nuevo circuito se devuelve junto con una lista que contiene los valores originales de los parámetros.
Parámetros
- qc (
QuantumCircuit) – El circuito cuántico que se va a parametrizar. - parameter_name (
str) – Nombre para elParameterVectorque representa los parámetros libres en el circuito ansatz devuelto.
Tipo de retorno
tuple[QuantumCircuit, list[float | None]]
Devuelve
(ansatz, parameter_values) de forma que ansatz.assign_parameters(parameter_values) sea idéntico a qc siempre que qc no contenga ya parámetros. Si qc ya tenía parámetros, entonces parameter_values contendrá None en las entradas correspondientes a esos parámetros.
Ejemplo:
Considere el siguiente circuito como ejemplo:
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")Si el circuito anterior se pasa a parametrize_circuit()devolverá un ansatz obtenido a partir de este circuito sustituyendo los parámetros numéricos por parámetros libres:
from qiskit_addon_aqc_tensor import parametrize_circuit
ansatz, initial_params = parametrize_circuit(qc)
ansatz.draw("mpl")Además, la función parametrize_circuit() proporciona parámetros que, cuando se vinculan al ansatz, dan como resultado un circuito idéntico al original:
ansatz.assign_parameters(initial_params).draw("mpl")Si el circuito original ya contenía parámetros, entonces los valores de los parámetros devueltos contendrán None en las entradas correspondientes a esos parámetros, y el código anterior no funcionará. El siguiente ejemplo muestra cómo recuperar el circuito original en este 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")