Skip to main content

HomOps Reference

Clamp

Clamp every element to a range. Client side only.

ClClient
RunsClient only
Changes shapeNo
Changes scaleNo
Levels spent0
RotatesNo
KeysNone

What it does

Clamp limits every element of the tensor to [min_val, max_val]. Values below the range become min_val, values above become max_val.
Clamping is a hard nonlinearity, so it never runs on encrypted data. It is a client-only operator: place it in client_pre to condition the input before encryption, or (the usual case) in client_post to bring the decrypted result back into a valid range, such as pixel values into [0, 255].
If a Clamp is placed at the leading or trailing edge of the hom section, the compiler moves it to the client for you; anywhere in the middle of hom fails, since the server can't run it.

Signature

Clamp(min_val, max_val)
No set_data.

Parameters

ParameterTypeDefaultDescription
min_valfloatrequiredLower bound, inclusive.
max_valfloatrequiredUpper bound, inclusive. Must be >= min_val.

Requirements

  • Client placement. client_pre, client_post, or an edge position in hom (auto-moved to the client). A Clamp the server would have to execute fails at compile time.

Shape effect - no

The output shape equals the input shape; only values change.

Scale effect - no

Clamp runs on cleartext, before encryption or after decryption; the ciphertext scale is not involved.

Level budget

Zero. Nothing encrypted happens here.

Keys

None.

Example

Edge detection: convolve on the server, then clip the decrypted image into [0, 1]:
pipeline.pyPYTHON
from lattica_build.client_ops import Clamp
from lattica_build.operators import HomConv, HomMatMul
from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline
from lattica_build.operators.composite.sequential import SequentialHomOp

pipeline = HomomorphicPipeline(
    client_pre=[HomMatMul((1, 3))],              # RGB -> grayscale
    hom=SequentialHomOp(
        HomConv((1, 100, 100), 1, 3, 1, 1, bias=False),
    ),
    client_post=[Clamp(0, 1)],                # clip after decrypt
    input_shape=(3, 100, 100),
)
For byte-range images the same pattern ends with Clamp(0, 255).

See also