← 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=Falsewhose 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^60fullAfter
HomConstMul2^60 × pt_scalefullAfter
HomModSwitchdivided by the dropped rowone row fewerSee also
- HomMul · HomSquare ·
HomConstMul - the automatic form,
with_modswitch=True Level budget - The chain - rows, columns, and what a drop does
Bootstrap - refresh the chain when dropping levels is not enough