Skip to main content

HomOps Reference

HomModSwitch

Drop a level from the chain and rescale, at a point you choose.

MsFHE
RunsServer
Changes shapeNo
Changes scaleYes - divided by the dropped prime
Levels spent1
RotatesNo
KeysNone

What it does

HomModSwitch performs one mod-switch, explicitly: it drops a prime from the modulus chain and divides the ciphertext's scale by it. This is the same operation that runs automatically inside with_modswitch=True on HomMul, HomSquare, and HomConstMul; the standalone form exists for when you want to control it yourself.
Two reasons to reach for it:
  • Placement. Rescale at a point where no multiply is happening, for example after a run of ops with with_modswitch=False whose growth you want to pay down in one chosen spot.
  • Choice of drop. The automatic form picks which row or column to drop; here you name it: a whole row, or columns within a row.
Most pipelines never write it; the automatic mod-switches cover them. How rows, columns, and drops work is explained on Level budget - The chain; this page assumes that model.

Signature

HomModSwitch(
    variant=0,          # 0 = ROW, 1 = COL
    relative_row=0,
    cols_to_drop=None,  # COL variant: list of column indices
)
No set_data.

Parameters

ParameterTypeDefaultDescription
variantint00 drops a whole row. 1 drops columns within a row.
relative_rowint0Which row to target, indexed among the ciphertext's currently active rows, not by absolute position in the original chain.
cols_to_dropSequence[int] | NoneNoneFor variant=1 only: the column indices to deactivate in the target row, not a count.
Rules that depend on the value
SettingRuleIf you break it
relative_rowMust point at an active row with something left to drop: columns for the COL variant, the full row for ROW.Compilation fails.
COL on the last columnDropping the last remaining column of a row removes the row itself; it behaves as a ROW drop.-

Requirements

  • A droppable target. The chain must still hold the row or column you name at the point where the op runs.
These surface as compilation errors; see Compilation errors.

Shape effect - no

The output shape equals the input shape. What changes is the ciphertext's chain state: one fewer row, or fewer columns in one row.

Scale effect - yes

Rule: the scale is multiplied by new_q / prev_q, that is, divided by whatever was dropped:
VariantEffect on scale
ROWDivided by the row's full modulus.
COLDivided by the dropped columns' primes.
This is the rescue operation for scale: every multiply grows it, and a mod-switch is how it comes back down. How far it comes down depends on the size of the prime that was dropped. How scale moves through a pipeline is on Ciphertext state - Scale.

Level budget

One drop, by definition: a whole row, or columns within a row (which counts against that row's remaining budget). This op is the spend that other pages call "1 with with_modswitch=True".
Compare the two forms of control:
pipeline.pyPYTHON
# Explicit: you name the drop
HomModSwitch(variant=0, relative_row=0)

# Automatic: the compiler picks, you can only restrict its choices
HomMul(with_modswitch=True, rows_budget=[3, 4])
How primes are organized in the chain is explained on Level budget - The chain.

Keys

None. A mod-switch is a linear operation on the ciphertext coefficients.

Example

Pay down accumulated growth at a chosen point:
pipeline.pyPYTHON
from lattica_build.operators import HomModSwitch
from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline
from lattica_build.operators.composite.sequential import SequentialHomOp

pipeline = HomomorphicPipeline(
    hom=SequentialHomOp(
        HomSquare(),                              # no rescale here
        HomConstMul(dims=(128,)),                 # nor here
        HomModSwitch(variant=0, relative_row=0),  # one drop pays for both
    ),
    input_shape=(128,),
)
pipeline.set_data(1, scale_vector)
Scale and chain through it:
Stagept_scaleChain
Input2^30full
After HomSquare2^60full
After HomConstMul2^60 × pt_scalefull
After HomModSwitchdivided by the dropped rowone row fewer

See also