Backend basado en el circuito Quimb
qiskit_addon_mpf.backends.quimb_circuit
Un backend de evolución temporal basado en circuitos que utiliza quimb.
Este backend sólo está disponible si se han instalado las dependencias opcionales:
pip install "qiskit-addon-mpf[quimb]"CircuitEvolver | Un motor de evolución temporal basado en circuitos cuánticos. |
CircuitState | Una representación tipo MPO de un estado de evolución temporal basada en circuitos cuánticos. |
Método subyacente
Quimb ofrece soporte directo para la simulación de circuitos cuánticos en forma de su representación basada en redes tensoriales quimb.tensor.Circuit basada en redes tensoriales. Podemos aprovechar esto para evitar cualquier algoritmo explícito de evolución temporal y, en su lugar, codificar directamente la evolución temporal en a QuantumCircuit y utilizar quimb para calcular el solapamiento entre dos circuitos de este tipo. Para más información, consulte su guía sobre Circuitos cuánticos.
Ejemplo de código
Esta sección muestra un ejemplo sencillo para empezar a utilizar este backend. El ejemplo muestra cómo crear las tres funciones de fábrica necesarias para la función setup_dynamic_lse().
El protocolo IdentityStateFactory ya lo cumple el constructor CircuitState por lo que el argumento identity_factory es trivial:
>>> from qiskit_addon_mpf.backends.quimb_circuit import CircuitState
>>> identity_factory = CircuitStateLa configuración del CircuitEvolver es un poco más complicada. Requiere un objeto QuantumCircuit como entrada, donde el Parameter debe tomar el lugar del paso de tiempo de los métodos Trotter (dt).
Para mostrar cómo se construye una plantilla de circuito de Trotter parametrizada de este tipo, reutilizamos el mismo Hamiltoniano y fórmula de Suzuki-Trotter de segundo orden que en quimb_layers.
>>> from qiskit.quantum_info import SparsePauliOp
>>> hamil = SparsePauliOp.from_sparse_list(
... [("ZZ", (i, i+1), 1.0) for i in range(0, 9, 2)] +
... [("Z", (i,), 0.5) for i in range(10)] +
... [("ZZ", (i, i+1), 1.0) for i in range(1, 9, 2)] +
... [("X", (i,), 0.25) for i in range(10)],
... num_qubits=10,
... )Pero esta vez, especificamos un Parameter como argumento time al construir los circuitos reales.
>>> from functools import partial
>>> from qiskit.circuit import Parameter
>>> from qiskit.synthesis import SuzukiTrotter
>>> from qiskit_addon_mpf.backends.quimb_circuit import CircuitEvolver
>>> from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
>>> dt = Parameter("dt")
>>> suzuki_2 = generate_time_evolution_circuit(hamil, time=dt, synthesis=SuzukiTrotter(order=2))
>>> approx_evolver_factory = partial(CircuitEvolver, circuit=suzuki_2)Es necesario que el nombre del Parameter ¡sea dt!
Podemos elegir una fórmula de Trotter de orden superior para la exact_evolver_factory. Pero tenga en cuenta que, una vez más, debemos utilizar un circuito parametrizado, incluso si vinculamos inmediatamente su parámetro al construir la función partial .
>>> suzuki_4 = generate_time_evolution_circuit(hamil, time=dt, synthesis=SuzukiTrotter(order=4))
>>> exact_evolver_factory = partial(CircuitEvolver, circuit=suzuki_4, dt=0.05)Estas funciones de fábrica pueden utilizarse ahora para ejecutar el programa setup_dynamic_lse(). Consulte su documentación para obtener más detalles al respecto.