ExpValFun_functions — Circuit Primitives¶
Pure functions returning QuantumCircuit objects. No class state — designed to be
passed as callables in the args dictionary consumed by QAE_Optimizer.
qiskit_impl.ExpValFun_functions.demand_constraint_preserving_mixer ¶
Mixing operator which preserves the demand constraint.
XY mixer U_d(β) that preserves the Hamming weight (= wind demand constraint).
For every pair (j, k) of wind qubits, applies SWAP^β: SWAP^β = exp(-i βπ/2 · (XX+YY)/2)
The XX+YY Hamiltonian moves excitations between qubits without changing their total count, so sum(y) = wind_demand is preserved throughout DQA evolution. This makes the Dicke-state initial condition self-consistent: the entire trajectory stays within the feasible subspace.
Eq. (39) of the paper. amplitude = β (decreases from 1 to 0 during annealing).
Source code in qiskit_impl/ExpValFun_functions.py
qiskit_impl.ExpValFun_functions.cost_operator ¶
Our cost operator.
constraint_amplitude will be recourse for the constraint-preserving mixer,
and a penalty weight otherwise.
Phase (cost) operator U_q(γ) encoding second-stage costs as quantum phases.
For each wind turbine j, applies two CP (controlled-phase) gates:
CP(γ · c_y[j] / cost_norm) on [pdf_reg[j], y_reg[j]] → phase e^{iγc_y/norm} when BOTH y[j]=|1⟩ AND ξ[j]=|1⟩ (turbine ON + wind available → operational cost c_y[j])
X(pdf_reg[j]) then CP(γ · c_r / cost_norm) then X(pdf_reg[j]) → phase e^{iγc_r/norm} when y[j]=|1⟩ AND ξ[j]=|0⟩ (turbine ON + no wind → recourse cost c_r)
The CP gate acts as exp(iθ |1⟩⟨1| ⊗ |1⟩⟨1|), i.e., it encodes the diagonal cost Hamiltonian H_C as a phase on computational basis states.
Corresponds to U_q in Eq. (42) of the paper.
amplitude = γ annealing parameter; args['cost_norm'] prevents phase wrapping.
Source code in qiskit_impl/ExpValFun_functions.py
qiskit_impl.ExpValFun_functions.cost_scenario_operator ¶
Source code in qiskit_impl/ExpValFun_functions.py
qiskit_impl.ExpValFun_functions.single_oracle_sin_inconstraint ¶
Compute the oracle onto an ancilla qubit — assuming our states are in-constraint, using the sin approximation.
Practical oracle F_sin (Eq. 45 of paper) using the sin-approximation.
For each turbine j, applies two CCRY (doubly-controlled-RY) rotations on the ancilla:
CCRY(π·c_y[j]/norm) on [y_reg[j], pdf_reg[j]] → ancilla → fires when turbine j is ON (y[j]=|1⟩) AND wind is available (ξ[j]=|1⟩) → rotates ancilla by π·c_y/norm (encodes operational cost as amplitude)
X(pdf_reg[j]) → CCRY(π·c_r/norm) → X(pdf_reg[j]) → fires when y[j]=|1⟩ AND ξ[j]=|0⟩ (recourse scenario) → rotates ancilla by π·c_r/norm
After F_sin: Pr[ancilla=|1⟩] ≈ q̄(y,ξ) = q(y,ξ)/norm (normalized cost).
The approximation sin(θ)≈θ is valid when angles are small (c/norm << 1). Efficient: requires only 2·n_y two-qubit-controlled RY gates instead of O(2^n).
Source code in qiskit_impl/ExpValFun_functions.py
qiskit_impl.ExpValFun_functions.dicke_state_circuit ¶
Reference: https://arxiv.org/pdf/1904.07358.pdf
Prepare the Dicke state |D_n^k⟩ on n = args['n_y'] qubits with k = args['w_d'] ones.
The Dicke state is a UNIFORM superposition over all n-bit strings with exactly k ones:
|D_n^k⟩ = 1/√C(n,k) Σ_{|y|=k} |y⟩
This is the initial state for DQA: every term already satisfies the demand constraint sum(y) = wind_demand. The XY mixer then keeps the state within this feasible subspace throughout the annealing.
Uses the SCS (Splitting-Coherence-Splitting) construction from Bärtschi & Eidenbenz, arXiv:1904.07358. Gate count O(n*k), no ancilla.
Source code in qiskit_impl/ExpValFun_functions.py
qiskit_impl.ExpValFun_functions.alternating_operator_ansatz ¶
Creates alternating ansatz circuit given circuits for cost operator and mixer operator. Input: args - dict containing num_qubits, gate used, graph edge list, angle (Parameter), cost_operator_circuit (Function), initial_state (QuantumCircuit), mixer_operator_circuit (Function), cost_qubits, ancilla_qubits, Theta (list). Output: QuantumCircuit
Build the DQA (Discrete Quantum Annealing) ansatz circuit U_DQA.
This is the QAOA-style alternating-operator ansatz:
U_DQA = [initial_state] ⊗ [pdf_state]
· Π_i (cost_op or mixer_op)(Theta[i])
Layout
y_reg (wind turbines) : initialized with Dicke state |D_n^{w_d}⟩ pdf_reg (wind scenarios) : initialized with PDF state |ξ⟩ encoding Pr[ξ]
Then alternating layers indexed by Theta (the variational angles): even i : cost_operator_circuit(Theta[i]) on y_reg + pdf_reg (encodes second-stage cost as phase) odd i : mixer_operator_circuit(Theta[i]) on y_reg only (mixes turbine decisions while preserving demand constraint)
The angles Theta are set by the linear annealing schedule s(t) = t/T, making this a parameterized quantum circuit that approximates adiabatic evolution.