← HomOps Reference
HomPolyEval
Fit and evaluate a function approximation on an encrypted value.
PePolynomials
RunsServer
Changes shapeNo
Changes scaleYes - grows through the evaluation
Levels spentSeveral - grows with the degree
RotatesNo
KeysSquare key
What it does
HomPolyEval is a helper that fits a Chebyshev polynomial to a callable func at a chosen degree, then evaluates that approximation on every ciphertext element. This is how smooth nonlinearities run on encrypted data.The evaluation uses a baby-step / giant-step schedule, so a degree-
d polynomial costs far fewer multiplications than d, but it is still deep: expect it to spend several levels, more for higher degrees.For already-computed Chebyshev coefficients, use the registered leaf HomPolyEvalBase instead.
ClassWhat it approximates
HomPolyIndicatorAn indicator: 1 near a target value, 0 elsewhere. Used to select matches in search pipelines.
HomPolyThresholdA step: 0 below a margin, 1 above it. Variants
sigmoid, piecewise_linear, minimax.Both construct polynomial approximations with their coefficients computed for you from the degree and shaping parameters.
Signature
HomPolyEval( func, # required: callable to approximate on the domain degree, # required: Chebyshev degree left=-1, right=1, tol=1e-8, plot=False, rows_budget=None, )
The variants take the degree instead of coefficients:
HomPolyIndicator(deg, right=4, tol=1e-8, rows_budget=None) HomPolyThreshold(deg, variant='sigmoid', margin=(0.4, 0.6), tol=1e-5, out_val=1, domain_start=-1, rows_budget=None)
No
set_data; this helper fits coefficients at construction. Use HomPolyEvalBase when you need to supply coefficients directly.Parameters
ParameterTypeDefaultDescription
funccallablerequiredFunction to approximate on the configured domain.degreeintrequiredDegree of the Chebyshev approximation fitted to func.left, rightint-1, 1Domain passed to the fit and evaluation.tolfloat1e-8Skip near-identity rescale factors while evaluating.plotboolFalseShow a debug plot when fitting the approximation.rows_budgetsequenceNoneRestricts which levels the internal mod-switches may spend, by absolute row index. See rows_budget.HomPolyThreshold adds: variant (the curve family), margin (where the step happens), out_val (the high value), domain_start.Rules that depend on the value
SettingRuleIf you break it
left, rightThe actual input values must lie inside [left, right]. The polynomial is only a valid approximation on its domain; values outside it produce garbage, silently.Wrong results, not an error. Check the range your previous ops can produce.left, rightA domain other than [-1, 1] adds an affine remap step before evaluation, which can cost one extra mod-switch.-rows_budgetAt least one listed row must be droppable at each internal mod-switch.Compilation fails if none are eligible.Requirements
- Input in domain. The single most important rule for this operator: whatever arrives must fit in
[left, right]. This is a numerical requirement the compiler cannot check for you. - Square key. The internal Chebyshev multiplies are ciphertext multiplies; any pipeline with a
HomPolyEvalneeds the square key (generated for you during key generation). - Level headroom. The deepest operator here. Budget several levels and verify with the compile-time simulation before deploying; see Level budget.
Shape effect - no
The output shape equals the input shape; the polynomial is applied element by element.
Scale effect - yes
Scale grows through the evaluation and is paid down by the internal mod-switches as it goes; the final scale depends on the degree and the mod-switch schedule. You don't manage this step by step. What you do is check the compiled result: the pipeline's compile-time simulation reports the output scale, and that is the number to plan the next operator around.
How scale moves through a pipeline is on Ciphertext state - Scale.
Level budget
HomPolyEval spends levels at several points inside:PhaseLevels
Domain remap to
[-1, 1]0 or 1, only when [left, right] is not [-1, 1]The evaluation itself (baby steps, giant steps, recursion)Several; grows with the degree
The exact count for a given degree is settled at compile time; verify it with the compile-time simulation rather than estimating by hand. Optionally pin drops with
rows_budget:pipeline.pyPYTHON
HomPolyIndicator(deg=80, rows_budget=[0, 1, 3, 4, 5, 6])
How primes are organized in the chain is explained on Level budget - The chain.
Keys
Square key (relinearization key). The Chebyshev evaluation multiplies ciphertexts by ciphertexts, so every multiply is followed by a relinearization. Generated for you during key generation. No rotation key.
Example
Threshold in a search pipeline
After inner products, turn similarity scores into a 0/1 selection:
pipeline.pyPYTHON
from lattica_build.operators import HomPolyThreshold from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline from lattica_build.operators.composite.sequential import SequentialHomOp ROWS_BUDGET = [0, 1, 3, 4, 5, 6] pipeline = HomomorphicPipeline( hom=SequentialHomOp( HomPolyThreshold(deg=80, variant='sigmoid', rows_budget=ROWS_BUDGET), ), input_shape=(128,), )
The other variants differ only in the curve:
pipeline.pyPYTHON
HomPolyThreshold(deg=80, variant='piecewise_linear', rows_budget=ROWS_BUDGET) HomPolyThreshold(deg=80, variant='minimax', margin=(0.45, 0.9), out_val=1, domain_start=-0.5, rows_budget=ROWS_BUDGET)
Custom coefficients
For precomputed Chebyshev coefficients, construct HomPolyEvalBase:
pipeline.pyPYTHON
import numpy as np from lattica_build.operators import HomPolyEval, HomPolyEvalBase import torch # Helper: fit Chebyshev coeffs from a callable HomPolyEval(lambda x: np.maximum(x, 0), degree=16, left=-1, right=1) # Leaf: supply coeffs directly via HomPolyEvalBase coefs = torch.randn(64) # degree 63 HomPolyEvalBase(coefs, left=-2, right=2)
The inputs must genuinely lie in
[-2, 2] for the result to be meaningful.See also
- HomPolyEvalBase - the registered Chebyshev leaf behind this family
- HomPolyIndicator · HomPolyThreshold - ready-made coefficient builders
- HomSign - multi-stage sign built from PolyEval stages
- HomSquare - a single depth-1 nonlinearity, when a quadratic is enough
- Bootstrap - refresh when the level budget runs out
- Level budget - The chain - planning for deep operators