Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

qamomile.optimization.fqaoa

This module implements the Fermionic QAOA (FQAOA) converter for the Qamomile framework [yoshioka2023fermionic]. FQAOA translates the Hamiltonians into the representation of fermion systems, and the equality constraint is naturally incorporated as a constant number of particles condition.

The parameterized state β,γ|\vec{\beta},\vec{\gamma}\rangle of pp-layer QAOA is defined as:

β,γ=U(β,γ)0n=eiβp1HMeiγp1HPeiβ0HMeiγ0HPUinit0n|\vec{\beta},\vec{\gamma}\rangle = U(\vec{\beta},\vec{\gamma})|0\rangle^{\otimes n} = e^{-i\beta_{p-1} H_M}e^{-i\gamma_{p-1} H_P} \cdots e^{-i\beta_0 H_M}e^{-i\gamma_0 H_P} U_{init}|0\rangle^{\otimes n}

where HPH_P is the cost Hamiltonian, HMH_M is the mixer Hamiltonian and γl\gamma_l and βl\beta_l are the variational parameters. The 2p2p variational parameters are optimized classically to minimize the expectation value β,γHPβ,γ\langle \vec{\beta},\vec{\gamma}|H_P|\vec{\beta},\vec{\gamma}\rangle. UinitU_{init} prepares the initial state using Givens rotation gates [jiang2018quantum].

This module provides functionality to convert optimization problems which written by jijmodeling into FQAOA circuits (U(β,γ)U(\vec{\beta}, \vec{\gamma})), construct cost Hamiltonians (HPH_P), and decode quantum computation results.

The FQAOAConverter class extends the MathematicalProblemConverter base class, specializing in FQAOA-specific operations such as ansatz circuit generation and result decoding.

Key Features:

Overview

FunctionDescription
fqaoa_stateGenerate complete FQAOA state.
is_close_zeroCheck if a given floating-point value is close to zero within a small tolerance.
ClassDescription
ExecutableProgramA fully compiled program ready for execution.
FQAOAConverterFQAOA (Fermionic Quantum Approximate Optimization Algorithm) converter class.
MathematicalProblemConverter
TranspilerBase class for backend-specific transpilers.

Functions

fqaoa_state [source]

def fqaoa_state(
    p: qmc.UInt,
    linear: qmc.Dict[qmc.UInt, qmc.Float],
    quad: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
    num_qubits: qmc.UInt,
    num_fermions: qmc.UInt,
    givens_ij: qmc.Matrix[qmc.UInt],
    givens_theta: qmc.Vector[qmc.Float],
    hopping: qmc.Float,
    gammas: qmc.Vector[qmc.Float],
    betas: qmc.Vector[qmc.Float],
) -> qmc.Vector[qmc.Qubit]

Generate complete FQAOA state.

Parameters:

NameTypeDescription
pqmc.UIntNumber of FQAOA layers.
linearqmc.Dict[qmc.UInt, qmc.Float]Linear coefficients of Ising model.
quadqmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float]Quadratic coefficients of Ising model.
num_qubitsqmc.UIntNumber of qubits.
num_fermionsqmc.UIntNumber of fermions for initial state.
givens_ijqmc.Matrix[qmc.UInt]Matrix of shape (N, 2) with qubit index pairs for Givens rotations.
givens_thetaqmc.Vector[qmc.Float]Vector of length N with Givens rotation angles.
hoppingqmc.FloatHopping integral for the mixer.
gammasqmc.Vector[qmc.Float]Vector of gamma parameters.
betasqmc.Vector[qmc.Float]Vector of beta parameters.

Returns:

qmc.Vector[qmc.Qubit] — FQAOA state vector.


is_close_zero [source]

def is_close_zero(value: float, abs_tol = 1e-15) -> bool

Check if a given floating-point value is close to zero within a small tolerance.

Parameters:

NameTypeDescription
valuefloatThe floating-point value to check.

Returns:

bool — True if the value is close to zero, False otherwise.

Classes

ExecutableProgram [source]

class ExecutableProgram(Generic[T])

A fully compiled program ready for execution.

This is the Orchestrator - manages execution of mixed classical/quantum programs.

Example:

executable = transpiler.compile(kernel)

# Sample: multiple shots, returns counts
job = executable.sample(executor, shots=1000)
result = job.result()  # SampleResult with counts

# Run: single shot, returns typed result
job = executable.run(executor)
result = job.result()  # Returns kernel's return type
Constructor
def __init__(
    self,
    compiled_quantum: list[CompiledQuantumSegment[T]] = list(),
    compiled_classical: list[CompiledClassicalSegment] = list(),
    compiled_expval: list[CompiledExpvalSegment] = list(),
    execution_order: list[tuple[str, int]] = list(),
    output_refs: list[str] = list(),
    num_output_bits: int = 0,
) -> None
Attributes
Methods
get_circuits
def get_circuits(self) -> list[T]

Get all quantum circuits in execution order.

get_first_circuit
def get_first_circuit(self) -> T | None

Get the first quantum circuit, or None if no quantum segments.

run
def run(
    self,
    executor: QuantumExecutor[T],
    bindings: dict[str, Any] | None = None,
) -> RunJob[Any] | ExpvalJob

Execute once and return single result.

Parameters:

NameTypeDescription
executorQuantumExecutor[T]Backend-specific quantum executor.
bindingsdict[str, Any] | NoneParameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2}

Returns:

RunJob[Any] | ExpvalJob — RunJob that resolves to the kernel’s return type, or RunJob[Any] | ExpvalJob — ExpvalJob if the program contains expectation value computation.

Raises:

Example:

job = executable.run(executor, bindings={"gamma": [0.5]})
result = job.result()
print(result)  # 0.25 (for QFixed) or (0, 1) (for bits)
sample
def sample(
    self,
    executor: QuantumExecutor[T],
    shots: int = 1024,
    bindings: dict[str, Any] | None = None,
) -> SampleJob[Any]

Execute with multiple shots and return counts.

Parameters:

NameTypeDescription
executorQuantumExecutor[T]Backend-specific quantum executor.
shotsintNumber of shots to run.
bindingsdict[str, Any] | NoneParameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2}

Returns:

SampleJob[Any] — SampleJob that resolves to SampleResult with results.

Raises:

Example:

job = executable.sample(executor, shots=1000, bindings={"gamma": [0.5]})
result = job.result()
print(result.results)  # [(0.25, 500), (0.75, 500)]

FQAOAConverter [source]

class FQAOAConverter(MathematicalProblemConverter)

FQAOA (Fermionic Quantum Approximate Optimization Algorithm) converter class.

This class provides methods to convert optimization problems into FQAOA circuits, construct cost Hamiltonians, and decode quantum computation results.

Examples:

from qamomile.optimization.fqaoa import FQAOAConverter

# Initialize with a compiled optimization problem instance
fqaoa_converter = FQAOAConverter(compiled_instance, num_fermions=4)

# Generate cost Hamiltonian and transpile
cost_hamiltonian = fqaoa_converter.get_cost_hamiltonian()
executable = fqaoa_converter.transpile(transpiler, p=2)
Constructor
def __init__(
    self,
    instance: ommx.v1.Instance,
    num_fermions: int,
    normalize_ising: Optional[Literal['abs_max', 'rms']] = None,
)

Initialize the FQAOAConverter.

This method initializes the converter with the compiled instance of the optimization problem.

Parameters:

NameTypeDescription
instanceommx.v1.Instanceommx.v1.Instance.
num_fermionsintNumber of fermions. This means the constraint M=l,dxl,dM = \sum_{l,d} x_{l,d}.
normalize_isingLiteral[abs_max, rms] | NoneThe normalization method for the Ising Hamiltonian. Available options: - “abs_max”: Normalize by absolute maximum value - “rms”: Normalize by root mean square Defaults to None.
Attributes
Methods
cyclic_mapping
def cyclic_mapping(self) -> dict[tuple[int, int], int]

Get variable maps between decision variable indices (l,d)(l,d) and qubit index ii.

Return:

dict[tuple[int, int], int] : A variable map for ring driver.

get_cost_hamiltonian
def get_cost_hamiltonian(self) -> qm_o.Hamiltonian

Construct the Ising cost Hamiltonian from the spin model.

Builds a Pauli-Z Hamiltonian from the spin model’s linear and quadratic terms.

Returns:

qm_o.Hamiltonian — qm_o.Hamiltonian: The cost Hamiltonian.

get_fermi_orbital
def get_fermi_orbital(self) -> np.ndarray

Compute the single-particle wave functions of the occupied spin orbitals.

Return:

numpy.ndarray: A 2D numpy array of shape (num_fermions, num_qubits)

transpile
def transpile(
    self,
    transpiler: Transpiler,
    *,
    p: int,
    hopping: float = 1.0,
) -> ExecutableProgram

Compile FQAOA ansatz into an executable program with measurements.


MathematicalProblemConverter [source]

class MathematicalProblemConverter(abc.ABC)
Constructor
def __init__(self, instance: ommx.v1.Instance | BinaryModel) -> None
Attributes
Methods
decode
def decode(self, samples: SampleResult[list[int]]) -> BinarySampleSet

Decode quantum measurement results.

Returns results in the original vartype (BINARY or SPIN) that was provided when constructing the converter.

get_cost_hamiltonian
def get_cost_hamiltonian(self) -> qm_o.Hamiltonian

Construct the cost Hamiltonian.

Subclasses must implement this method to build the appropriate Hamiltonian for their specific algorithm (e.g., Pauli-Z for QAOA, QRAC-encoded for QRAO).

Returns:

qm_o.Hamiltonian — qm_o.Hamiltonian: The cost Hamiltonian.


Transpiler [source]

class Transpiler(ABC, Generic[T])

Base class for backend-specific transpilers.

Provides the full compilation pipeline from QKernel to executable program.

Usage:

transpiler = QiskitTranspiler()

Option 1: Full pipeline

executable = transpiler.compile(kernel, bindings={“theta”: 0.5}) results = executable.run(transpiler.executor())

Option 2: Step-by-step

block = transpiler.to_block(kernel) substituted = transpiler.substitute(block) affine = transpiler.inline(substituted) validated = transpiler.affine_validate(affine) folded = transpiler.constant_fold(validated, bindings={“theta”: 0.5}) analyzed = transpiler.analyze(folded) separated = transpiler.separate(analyzed) executable = transpiler.emit(separated, bindings={“theta”: 0.5})

Option 3: Just get the circuit (no execution)

circuit = transpiler.to_circuit(kernel, bindings={“theta”: 0.5})

With configuration (strategy overrides)

config = TranspilerConfig.with_strategies({“qft”: “approximate”}) transpiler = QiskitTranspiler(config=config)

Attributes
Methods
affine_validate
def affine_validate(self, block: Block) -> Block

Pass 1.5: Validate affine type semantics.

This is a safety net to catch affine type violations that may have bypassed frontend checks. Validates that quantum values are used at most once.

analyze
def analyze(self, block: Block) -> Block

Pass 2: Validate and analyze dependencies.

constant_fold
def constant_fold(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Pass 1.5: Fold constant expressions.

Evaluates BinOp operations when all operands are constants or bound parameters. This prevents quantum segment splitting from parametric expressions like phase * 2.

emit
def emit(
    self,
    separated: SimplifiedProgram,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
) -> ExecutableProgram[T]

Pass 4: Generate backend-specific code.

Parameters:

NameTypeDescription
separatedSimplifiedProgramThe separated program to emit
bindingsdict[str, Any] | NoneParameter values to bind at compile time
parameterslist[str] | NoneParameter names to preserve as backend parameters
executor
def executor(self, **kwargs: Any = {}) -> QuantumExecutor[T]

Create a quantum executor for this backend.

inline
def inline(self, block: Block) -> Block

Pass 1: Inline all CallBlockOperations.

lower_compile_time_ifs
def lower_compile_time_ifs(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Pass 1.75: Lower compile-time resolvable IfOperations.

Evaluates IfOperation conditions (including expression-derived conditions via CompOp/CondOp/NotOp) and replaces resolved ones with selected-branch operations. Phi outputs are substituted with selected-branch values throughout the block.

This prevents SeparatePass from seeing classical-only compile-time IfOperations that would otherwise split quantum segments.

separate
def separate(self, block: Block) -> SimplifiedProgram

Pass 3: Lower and split into quantum and classical segments.

Validates C→Q→C pattern with single quantum segment.

set_config
def set_config(self, config: TranspilerConfig) -> None

Set the transpiler configuration.

Parameters:

NameTypeDescription
configTranspilerConfigTranspiler configuration to use
substitute
def substitute(self, block: Block) -> Block

Pass 0.5: Apply substitutions (optional).

This pass replaces CallBlockOperation targets and sets strategy names on CompositeGateOperations based on config.

Parameters:

NameTypeDescription
blockBlockBlock to transform

Returns:

Block — Block with substitutions applied

to_block
def to_block(
    self,
    kernel: QKernel,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
) -> Block

Convert a QKernel to a Block.

Parameters:

NameTypeDescription
kernelQKernelThe QKernel to convert
bindingsdict[str, Any] | NoneConcrete values to bind at trace time (resolves array shapes)
parameterslist[str] | NoneNames to keep as unbound parameters

When bindings or parameters are provided, uses kernel.build() to properly resolve array shapes from the bound data. Otherwise uses the cached block_value for efficiency.

to_circuit
def to_circuit(self, kernel: QKernel, bindings: dict[str, Any] | None = None) -> T

Compile and extract just the quantum circuit.

This is a convenience method for when you just want the backend circuit without the full executable.

Parameters:

NameTypeDescription
kernelQKernelThe QKernel to compile
bindingsdict[str, Any] | NoneParameter values to bind

Returns:

T — Backend-specific quantum circuit

transpile
def transpile(
    self,
    kernel: QKernel,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
) -> ExecutableProgram[T]

Full compilation pipeline from QKernel to executable.

Parameters:

NameTypeDescription
kernelQKernelThe QKernel to compile
bindingsdict[str, Any] | NoneParameter values to bind (also resolves array shapes)
parameterslist[str] | NoneParameter names to preserve as backend parameters

Returns:

ExecutableProgram[T] — ExecutableProgram ready for execution

Raises:

Pipeline:

  1. to_block: Convert QKernel to Block

  2. substitute: Apply substitutions (if configured)

  3. inline: Inline CallBlockOperations

  4. affine_validate: Validate affine type semantics

  5. constant_fold: Fold constant expressions 5.5. lower_compile_time_ifs: Lower compile-time IfOperations 5.8. validate_while_contract: Validate while conditions are measurement-backed

  6. analyze: Validate and analyze dependencies

  7. separate: Split into quantum/classical segments

  8. emit: Generate backend-specific code

validate_while_contract
def validate_while_contract(self, block: Block) -> Block

Pass 1.8: Validate WhileOperation conditions are measurement-backed.

Rejects while patterns whose condition is not a measurement result (Bit from qmc.measure()). This prevents late ValueError at emit time for unsupported while forms.