Source code for uniqc.algorithmics.circuits.thermal_state

"""Thermal state preparation circuit."""

__all__ = ["thermal_state_circuit"]

from typing import List, Optional
import math

from uniqc.circuit_builder import Circuit


[docs] def thermal_state_circuit( circuit: Circuit, beta: float, qubits: Optional[List[int]] = None, ) -> None: r"""Prepare a thermal state via single-qubit rotations. For the transverse-field-free Hamiltonian :math:`H = \sum_i Z_i`, the thermal (Gibbs) state at inverse temperature :math:`\beta` factorises into a product of single-qubit states. Each qubit is prepared in .. math:: \sqrt{p_0}\,|0\rangle + \sqrt{p_1}\,|1\rangle where .. math:: p_0 = \frac{e^{\beta}}{e^{\beta}+e^{-\beta}}, \qquad p_1 = 1 - p_0. This is achieved by applying :math:`R_y(\theta)` with :math:`\theta = 2\arccos(\sqrt{p_0})` to every qubit independently. This is a lightweight, circuit-only counterpart of ``state_preparation.thermal_state`` for the default Hamiltonian case. Args: circuit: Quantum circuit to operate on (mutated in-place). beta: Inverse temperature (:math:`\beta > 0`). Larger values bias the state towards :math:`|0\rangle`. qubits: Qubit indices to use. ``None`` means all qubits of *circuit* (``list(range(circuit.qubit_num))``). Raises: ValueError: *beta* is negative. Example: >>> from uniqc.circuit_builder import Circuit >>> from uniqc.algorithmics.circuits import thermal_state_circuit >>> c = Circuit(3) >>> thermal_state_circuit(c, beta=1.0) """ if beta < 0: raise ValueError(f"beta must be non-negative, got {beta}") if qubits is None: qubits = list(range(circuit.qubit_num)) # Compute rotation angle: theta = 2 * arccos(sqrt(p0)) # p0 = e^beta / (e^beta + e^{-beta}) exp_beta = math.exp(beta) exp_neg_beta = math.exp(-beta) p0 = exp_beta / (exp_beta + exp_neg_beta) theta = 2.0 * math.acos(math.sqrt(p0)) for q in qubits: circuit.ry(q, theta)