Skip to main content

HomOps Reference

HomSign

Approximate the sign function on encrypted values, element by element.

SgPolynomials
RunsServer
Changes shapeNo
Changes scaleYes - via poly stages
Levels spentTunable - multi-stage PolyEval
RotatesNo
KeysSquare key

What it does

HomSign approximates the sign function sgn(x) with a composition of Chebyshev polynomial stages. Each stage sharpens the soft step; together they push positive values toward +1 and negative values toward -1.
It is a composite, not a registered leaf: the compiler expands it into nested HomPolyEvalBase ops. Scale is applied only on the last stage, so intermediate outputs stay in [-1, 1] for the next stage's fit.
Reach for HomSign when you need an encrypted soft step on its own, or as the core of HomCompare, HomMin, HomMax, and HomReLU.

Signature

HomSign(
    scale=1,
    x_accuracy=10,
    y_accuracy=10,
    left=-1,
    right=1.0,
    tol=1e-8,
    rows_budget=None,
)
No set_data; the Chebyshev stages are built at construction from the accuracy parameters.

Parameters

ParameterTypeDefaultDescription
scalefloat1Multiplies the last stage's coefficients only. Earlier stages stay unscaled so their outputs remain in the fitted [-1, 1] range.
x_accuracyint10Horizontal accuracy for the Remez sign approximation. Higher values mean more stages / sharper steps and more levels.
y_accuracyint10Vertical accuracy. Internally passed as y_accuracy - 1 to the sign coefficient generator.
left, rightfloat-1, 1.0Input domain for the first poly stage only. Later stages always use [-1, 1].
tolfloat1e-8Forwarded to each HomPolyEvalBase stage.
rows_budgetsequenceNoneRestricts which levels the nested mod-switches may spend. Forwarded to every stage. See rows_budget.
Rules that depend on the value
SettingRuleIf you break it
left, rightInputs should lie in [left, right] for the first stage. Stages after the first always use [-1, 1].Wrong results, not an error. Values outside the fitted domain produce garbage silently.
scaleOnly the last stage is scaled; intermediate Sign iterates stay in the fitted [-1, 1] range.-

Requirements

  • Square key. Each nested PolyEval stage multiplies ciphertexts; any pipeline with a HomSign needs the square key (generated for you during key generation).
  • Level headroom. Depth is the sum of all stage depths and can grow large at high accuracy. Plan levels like a multi-stage PolyEval chain.
  • Input in domain. Values should fit in [left, right] for the first stage. The compiler cannot check this for you.
  • Not a leaf. HomSign expands into nested ops; it is not a registered backend leaf.

Shape effect - no

The output shape equals the input shape; each Chebyshev stage is applied element by element.

Scale effect - yes

Each nested PolyEval stage grows and adjusts scale per its internal mul / mod-switch schedule. The final amplitude also depends on scale on the last stage. Check the compile-time simulation for the output scale rather than estimating by hand.
How scale moves through a pipeline is on Ciphertext state - Scale.

Level budget

Levels spent equal the sum over stages of each PolyEval's cost (domain remap on stage 0 if needed, plus evaluation depth per degree). Accuracy parameters control how many stages and how deep each is; that is the tunable depth.
How primes are organized in the chain is explained on Level budget - The chain.

Keys

Square key (relinearization key). Required through the nested PolyEval children. Generated for you during key generation. No rotation key.

Example

Build a standalone sign, or let Compare wrap one for you:
pipeline.pyPYTHON
from lattica_build.operators import HomSign, HomCompare

sgn = HomSign(scale=1.0, x_accuracy=10, y_accuracy=10, left=-1, right=1)

# HomCompare builds HomSign(scale=0.5, ...) then adds 0.5
cmp = HomCompare(x_accuracy=12, y_accuracy=12, left=-1, right=1)

See also