Skip to content

Archived LunaModel 0.5.9 documentation

You are reading the old LunaModel 0.5.9 documentation. The regular documentation describes LunaModel >=0.6.0; use the latest documentation unless you explicitly need the old release.

Advanced Transformation Topics

Advanced techniques for model transformations in LunaModel.

Sequential Passes

Apply multiple passes in sequence using PassManager.

Python
from luna_model.transformation import PassManager
from luna_model.transformation.passes import ChangeSensePass, BinarySpinPass
from luna_model import Sense, Vtype

# Apply passes in sequence
pm = PassManager([
    ChangeSensePass(Sense.MIN),
    BinarySpinPass(Vtype.SPIN, prefix=None),
])

ir = pm.run(model)
transformed = ir.model

Pipeline

Group passes together as a single unit.

Python
from luna_model.transformation import Pipeline, PassManager
from luna_model.transformation.passes import ChangeSensePass, BinarySpinPass
from luna_model import Sense, Vtype

# Create a named pipeline
preprocessing = Pipeline([
    ChangeSensePass(Sense.MIN),
    BinarySpinPass(Vtype.SPIN, prefix=None),
], name="preprocessing")

# Use in PassManager
pm = PassManager([preprocessing])
ir = pm.run(model)

Conditional Execution with IfElsePass

Execute different passes based on runtime conditions.

Python
from luna_model.transformation import PassManager, Pipeline, IfElsePass
from luna_model.transformation import analyse
from luna_model.transformation.passes import BinarySpinPass, MaxBiasAnalysis
from luna_model import Vtype

# Analysis to check model properties
@analyse(name="model-complexity")
def check_model_complexity(model, cache):
    """Analyze model complexity."""
    num_vars = model.num_variables()
    num_constraints = model.num_constraints()
    return {"vars": num_vars, "constraints": num_constraints}

# Conditional transformation based on model size
conditional = IfElsePass(
    requires=["model-complexity"],
    condition=lambda cache: cache["model-complexity"]["vars"] > 100,
    then=Pipeline([BinarySpinPass(Vtype.SPIN, prefix=None)]),
    otherwise=Pipeline([]),
    name="conditional-spin",
)

pm = PassManager([check_model_complexity, conditional])
ir = pm.run(model)

Using AnalysisCache

Passes can share data through the AnalysisCache.

Python
from luna_model.transformation import analyse, transform, ActionType, PassManager

# Analysis pass stores data in cache
@analyse(name="compute-stats")
def compute_stats(model, cache):
    """Compute model statistics."""
    return {
        "num_vars": model.num_variables(),
        "num_constraints": model.num_constraints(),
    }

# Transformation uses cached analysis
@transform(name="use-stats", requires=["compute-stats"])
def use_stats(model, cache):
    """Transform based on cached statistics."""
    stats = cache["compute-stats"]

    # Only apply transformation if model is small enough
    if stats["num_vars"] < 50:
        model.sense = Sense.MIN
        return model, ActionType.DID_TRANSFORM

    return model, ActionType.DID_NOTHING

pm = PassManager([compute_stats, use_stats])
ir = pm.run(model)

Backwards Transformation

Map solutions from transformed models back to original variable space.

Python
from luna_model.transformation import PassManager
from luna_model.transformation.passes import BinarySpinPass
from luna_model import Vtype

# Transform model
pm = PassManager([BinarySpinPass(Vtype.SPIN, prefix=None)])
ir = pm.run(model)
transformed_model = ir.model

# Solve transformed model (solver not shown)
# solution = solve(transformed_model)

# Map solution back to original model variables
# original_solution = pm.backwards(solution, ir)

Creating Reusable Pipelines

Python
from luna_model.transformation import Pipeline
from luna_model.transformation.passes import ChangeSensePass, BinarySpinPass
from luna_model import Sense, Vtype

def create_spin_conversion_pipeline():
    """Create pipeline for spin variable conversion."""
    return Pipeline([
        ChangeSensePass(Sense.MIN),
        BinarySpinPass(Vtype.SPIN, prefix=None),
    ], name="spin-conversion")

# Use the pipeline
spin_pipeline = create_spin_conversion_pipeline()
pm = PassManager([spin_pipeline])
ir = pm.run(model)

See Also