Skip to content

Metrics and losses

concrete_fhe_toolkit.ml.core

Core routines and execution logic for encrypted ML.

manhattan_distance

manhattan_distance(array1: Union[ndarray, List[Any]], array2: Union[ndarray, List[Any]]) -> Any

Calculate the Manhattan (L1) distance between two encrypted arrays.

This is often used as a robust distance metric for clustering or k-nearest neighbor algorithms under encryption, since it avoids the expensive squaring operations required by Euclidean distance.

Example
from concrete_fhe_toolkit.ml.core import manhattan_distance

# Inside an FHE circuit
# dist = manhattan_distance([enc_x1, enc_y1], [enc_x2, enc_y2])

Parameters:

Name Type Description Default
array1 Union[ndarray, List[Any]]

The first encrypted array.

required
array2 Union[ndarray, List[Any]]

The second encrypted array.

required

Returns:

Name Type Description
Any Any

The Manhattan distance.

Source code in src/concrete_fhe_toolkit/ml/core.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def manhattan_distance(array1: Union[np.ndarray, List[Any]], array2: Union[np.ndarray, List[Any]]) -> Any:
    """Calculate the Manhattan (L1) distance between two encrypted arrays.

    This is often used as a robust distance metric for clustering or
    k-nearest neighbor algorithms under encryption, since it avoids 
    the expensive squaring operations required by Euclidean distance.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import manhattan_distance

        # Inside an FHE circuit
        # dist = manhattan_distance([enc_x1, enc_y1], [enc_x2, enc_y2])
        ```

    Args:
        array1 (Union[np.ndarray, List[Any]]): The first encrypted array.
        array2 (Union[np.ndarray, List[Any]]): The second encrypted array.

    Returns:
        Any: The Manhattan distance.
    """
    if(len(array1) != len(array2)):
        raise ValueError("The array sizes must be equal")
    return np.sum(np.absolute(_ensure_tensor(array1) - _ensure_tensor(array2)))

hamming_distance

hamming_distance(array1: Union[ndarray, List[Any]], array2: Union[ndarray, List[Any]]) -> Any

Calculate the Hamming distance (number of mismatches) between two encrypted arrays.

This is useful for comparing binary feature vectors or categorical data, measuring the number of positions where the two arrays differ.

Example
from concrete_fhe_toolkit.ml.core import hamming_distance

# Inside an FHE circuit
# dist = hamming_distance([enc_a1, enc_b1], [enc_a2, enc_b2])

Parameters:

Name Type Description Default
array1 Union[ndarray, List[Any]]

The first encrypted array.

required
array2 Union[ndarray, List[Any]]

The second encrypted array.

required

Returns:

Name Type Description
Any Any

The Hamming distance.

Source code in src/concrete_fhe_toolkit/ml/core.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
def hamming_distance(array1: Union[np.ndarray, List[Any]], array2: Union[np.ndarray, List[Any]]) -> Any:
    """Calculate the Hamming distance (number of mismatches) between two encrypted arrays.

    This is useful for comparing binary feature vectors or categorical data, 
    measuring the number of positions where the two arrays differ.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import hamming_distance

        # Inside an FHE circuit
        # dist = hamming_distance([enc_a1, enc_b1], [enc_a2, enc_b2])
        ```

    Args:
        array1 (Union[np.ndarray, List[Any]]): The first encrypted array.
        array2 (Union[np.ndarray, List[Any]]): The second encrypted array.

    Returns:
        Any: The Hamming distance.
    """
    if(len(array1) != len(array2)):
        raise ValueError("The array sizes must be equal")

    return np.sum(_ensure_tensor(array1) != _ensure_tensor(array2))

euclidean_distance_squared

euclidean_distance_squared(array1: Union[ndarray, List[Any]], array2: Union[ndarray, List[Any]]) -> Any

Calculate the squared Euclidean (L2) distance between two encrypted arrays.

Often used in k-means clustering or RBF kernels. Using the squared distance avoids the need for an expensive square root operation.

Example
from concrete_fhe_toolkit.ml.core import euclidean_distance_squared

# Inside an FHE circuit
# dist_sq = euclidean_distance_squared(enc_point_1, enc_point_2)

Parameters:

Name Type Description Default
array1 Union[ndarray, List[Any]]

The first encrypted array.

required
array2 Union[ndarray, List[Any]]

The second encrypted array.

required

Returns:

Name Type Description
Any Any

The squared Euclidean distance.

Source code in src/concrete_fhe_toolkit/ml/core.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
def euclidean_distance_squared(array1: Union[np.ndarray, List[Any]], array2: Union[np.ndarray, List[Any]]) -> Any:
    """Calculate the squared Euclidean (L2) distance between two encrypted arrays.

    Often used in k-means clustering or RBF kernels. Using the squared 
    distance avoids the need for an expensive square root operation.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import euclidean_distance_squared

        # Inside an FHE circuit
        # dist_sq = euclidean_distance_squared(enc_point_1, enc_point_2)
        ```

    Args:
        array1 (Union[np.ndarray, List[Any]]): The first encrypted array.
        array2 (Union[np.ndarray, List[Any]]): The second encrypted array.

    Returns:
        Any: The squared Euclidean distance.
    """
    if(len(array1) != len(array2)):
        raise ValueError("The array sizes must be equal")
    return np.sum((_ensure_tensor(array1)-_ensure_tensor(array2)) ** 2)

mean_squared_error

mean_squared_error(array1: Union[ndarray, List[Any]], array2: Union[ndarray, List[Any]]) -> Any

Calculate the Mean Squared Error (MSE) between two encrypted arrays.

A standard metric for regression tasks. It measures the average of the squares of the errors (the difference between estimated values and the actual value).

Example
from concrete_fhe_toolkit.ml.core import mean_squared_error

# Inside an FHE circuit
# mse = mean_squared_error(enc_predictions, enc_true_values)

Parameters:

Name Type Description Default
array1 Union[ndarray, List[Any]]

The first encrypted array.

required
array2 Union[ndarray, List[Any]]

The second encrypted array.

required

Returns:

Name Type Description
Any Any

The Mean Squared Error.

Source code in src/concrete_fhe_toolkit/ml/core.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def mean_squared_error(array1: Union[np.ndarray, List[Any]], array2: Union[np.ndarray, List[Any]]) -> Any:
    """Calculate the Mean Squared Error (MSE) between two encrypted arrays.

    A standard metric for regression tasks. It measures the average 
    of the squares of the errors (the difference between estimated values 
    and the actual value).

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import mean_squared_error

        # Inside an FHE circuit
        # mse = mean_squared_error(enc_predictions, enc_true_values)
        ```

    Args:
        array1 (Union[np.ndarray, List[Any]]): The first encrypted array.
        array2 (Union[np.ndarray, List[Any]]): The second encrypted array.

    Returns:
        Any: The Mean Squared Error.
    """
    if(len(array1) != len(array2)):
            raise ValueError("The array sizes must be equal")
    return euclidean_distance_squared(array1,array2) // len(array1)

mean_absolute_error

mean_absolute_error(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Any

Calculate the Mean Absolute Error (MAE) between predictions and true values.

A robust alternative to MSE that is less sensitive to outliers.

Example
from concrete_fhe_toolkit.ml.core import mean_absolute_error

# Inside an FHE circuit
# mae = mean_absolute_error(enc_predictions, enc_true_values)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
Any Any

The Mean Absolute Error.

Source code in src/concrete_fhe_toolkit/ml/core.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def mean_absolute_error(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
    """Calculate the Mean Absolute Error (MAE) between predictions and true values.

    A robust alternative to MSE that is less sensitive to outliers.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import mean_absolute_error

        # Inside an FHE circuit
        # mae = mean_absolute_error(enc_predictions, enc_true_values)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Any: The Mean Absolute Error.
    """
    distance = manhattan_distance(y_preds,y_trues)
    return distance // len(y_trues)

accuracy_score

accuracy_score(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Any

[Client-Side Helper] This function is intended for cleartext evaluation only. Do not compile it with FHE due to Table Lookup limits or list return types.

Calculate the percentage accuracy score between predictions and true labels.

Returns an integer percentage [0, 100]. Useful for evaluating classification models directly on encrypted data.

Example
from concrete_fhe_toolkit.ml.core import accuracy_score

# Inside an FHE circuit
# acc_pct = accuracy_score(enc_predictions, enc_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
Any Any

The accuracy score percentage.

Source code in src/concrete_fhe_toolkit/ml/core.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
@client_side_helper
def accuracy_score(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
    """
    [Client-Side Helper] This function is intended for cleartext evaluation only.
    Do not compile it with FHE due to Table Lookup limits or list return types.

    Calculate the percentage accuracy score between predictions and true labels.

    Returns an integer percentage [0, 100]. Useful for evaluating 
    classification models directly on encrypted data.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import accuracy_score

        # Inside an FHE circuit
        # acc_pct = accuracy_score(enc_predictions, enc_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Any: The accuracy score percentage.
    """
    if(len(y_preds) != len(y_trues)):
        raise ValueError("The array sizes must be equal")

    true_predictions = np.sum(_ensure_tensor(y_preds) == _ensure_tensor(y_trues))
    return true_predictions * 100 // len(y_trues)

true_positives

true_positives(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> int

Calculate the number of True Positives in binary classification.

Assuming 1 is positive and 0 is negative, this counts instances where both the prediction and the true label are 1.

Example
from concrete_fhe_toolkit.ml.core import true_positives

# Inside an FHE circuit
# tp = true_positives(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
int int

The number of true positives.

Source code in src/concrete_fhe_toolkit/ml/core.py
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
def true_positives(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> int:
    """Calculate the number of True Positives in binary classification.

    Assuming 1 is positive and 0 is negative, this counts instances 
    where both the prediction and the true label are 1.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import true_positives

        # Inside an FHE circuit
        # tp = true_positives(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        int: The number of true positives.
    """
    if(len(y_preds) != len(y_trues)):
        raise ValueError("The array sizes must be equal")

    num_of_true_positives = np.sum(1 == np.multiply(_ensure_tensor(y_preds), _ensure_tensor(y_trues)))
    return num_of_true_positives

true_negatives

true_negatives(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> int

Calculate the number of True Negatives in binary classification.

Assuming 1 is positive and 0 is negative, this counts instances where both the prediction and the true label are 0.

Example
from concrete_fhe_toolkit.ml.core import true_negatives

# Inside an FHE circuit
# tn = true_negatives(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
int int

The number of true negatives.

Source code in src/concrete_fhe_toolkit/ml/core.py
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
def true_negatives(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> int:
    """Calculate the number of True Negatives in binary classification.

    Assuming 1 is positive and 0 is negative, this counts instances 
    where both the prediction and the true label are 0.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import true_negatives

        # Inside an FHE circuit
        # tn = true_negatives(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        int: The number of true negatives.
    """
    if(len(y_preds) != len(y_trues)):
        raise ValueError("The array sizes must be equal")

    num_of_true_negatives = np.sum(0 == _ensure_tensor(y_preds) + _ensure_tensor(y_trues))
    return num_of_true_negatives

false_negatives

false_negatives(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> int

Calculate the number of False Negatives in binary classification.

Example
from concrete_fhe_toolkit.ml.core import false_negatives

# Inside an FHE circuit
# fn = false_negatives(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
int int

The number of false negatives.

Source code in src/concrete_fhe_toolkit/ml/core.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
def false_negatives(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> int:
    """Calculate the number of False Negatives in binary classification.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import false_negatives

        # Inside an FHE circuit
        # fn = false_negatives(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        int: The number of false negatives.
    """
    num_of_positives = array_sum(y_trues)
    return num_of_positives - true_positives(y_preds, y_trues)

false_positives

false_positives(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> int

Calculate the number of False Positives in binary classification.

Example
from concrete_fhe_toolkit.ml.core import false_positives

# Inside an FHE circuit
# fp = false_positives(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
int int

The number of false positives.

Source code in src/concrete_fhe_toolkit/ml/core.py
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
def false_positives(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> int:
    """Calculate the number of False Positives in binary classification.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import false_positives

        # Inside an FHE circuit
        # fp = false_positives(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        int: The number of false positives.
    """
    num_of_negatives = len(y_trues) - array_sum(y_trues)
    return num_of_negatives - true_negatives(y_preds, y_trues)

confusion_matrix

confusion_matrix(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Union[np.ndarray, List[List[Any]]]

[Client-Side Helper] This function is intended for cleartext evaluation only. Do not compile it with FHE due to Table Lookup limits or list return types.

Generate a confusion matrix [[TN, FP], [FN, TP]] for binary classification.

This is extremely useful for calculating various ML metrics (like precision, recall, F1) securely over encrypted predictions.

Example
from concrete_fhe_toolkit.ml.core import confusion_matrix

# Inside an FHE circuit
# matrix = confusion_matrix(enc_binary_preds, enc_binary_labels)
# tn, fp = matrix[0]
# fn, tp = matrix[1]

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Type Description
Union[ndarray, List[List[Any]]]

Union[np.ndarray, List[List[Any]]]: The confusion matrix [[TN, FP], [FN, TP]].

Source code in src/concrete_fhe_toolkit/ml/core.py
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
@client_side_helper
def confusion_matrix(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Union[np.ndarray, List[List[Any]]]:
    """
    [Client-Side Helper] This function is intended for cleartext evaluation only.
    Do not compile it with FHE due to Table Lookup limits or list return types.

    Generate a confusion matrix [[TN, FP], [FN, TP]] for binary classification.

    This is extremely useful for calculating various ML metrics (like precision, 
    recall, F1) securely over encrypted predictions.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import confusion_matrix

        # Inside an FHE circuit
        # matrix = confusion_matrix(enc_binary_preds, enc_binary_labels)
        # tn, fp = matrix[0]
        # fn, tp = matrix[1]
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Union[np.ndarray, List[List[Any]]]: The confusion matrix [[TN, FP], [FN, TP]].
    """
    tp = true_positives(y_preds,y_trues)
    tn = true_negatives(y_preds,y_trues)
    fn = false_negatives(y_preds,y_trues)
    fp = false_positives(y_preds,y_trues)
    return [[tn,fp],[fn,tp]]

hinge_loss

hinge_loss(y_pred: Any, y_true: Any) -> Any

Calculate the encrypted Hinge Loss for a single prediction and true value.

Hinge loss is commonly used for "maximum-margin" classification, most notably for Support Vector Machines (SVMs). The true label should be +1 or -1.

Example
from concrete_fhe_toolkit.ml.core import hinge_loss

# Inside an FHE circuit
# loss = hinge_loss(enc_pred_score, enc_true_label)

Parameters:

Name Type Description Default
y_pred Any

Prediction.

required
y_true Any

True value.

required

Returns:

Name Type Description
Any Any

The Hinge Loss.

Source code in src/concrete_fhe_toolkit/ml/core.py
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
def hinge_loss(y_pred: Any, y_true: Any) -> Any:
    """Calculate the encrypted Hinge Loss for a single prediction and true value.

    Hinge loss is commonly used for "maximum-margin" classification, most 
    notably for Support Vector Machines (SVMs). The true label should be +1 or -1.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import hinge_loss

        # Inside an FHE circuit
        # loss = hinge_loss(enc_pred_score, enc_true_label)
        ```

    Args:
        y_pred (Any): Prediction.
        y_true (Any): True value.

    Returns:
        Any: The Hinge Loss.
    """
    return maximum(0, 1-(y_true*y_pred))

l1_norm

l1_norm(array: Union[ndarray, List[Any]]) -> Any

Calculate the L1 norm (sum of absolute values) of an array.

Example
from concrete_fhe_toolkit.ml.core import l1_norm

# In FHE circuit: l1_norm([-1, 5, -10]) -> 16

Parameters:

Name Type Description Default
array Union[ndarray, List[Any]]

The encrypted array or list of elements.

required

Returns:

Name Type Description
Any Any

The L1 norm.

Source code in src/concrete_fhe_toolkit/ml/core.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
def l1_norm(array: Union[np.ndarray, List[Any]]) -> Any:
    """Calculate the L1 norm (sum of absolute values) of an array.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import l1_norm

        # In FHE circuit: l1_norm([-1, 5, -10]) -> 16
        ```

    Args:
        array (Union[np.ndarray, List[Any]]): The encrypted array or list of elements.

    Returns:
        Any: The L1 norm.
    """
    total = np.sum(np.absolute(_ensure_tensor(array)))
    return total

compile_hinge_loss

compile_hinge_loss(min_value: int = -15, max_value: int = 15, *, configuration: Optional[Configuration] = None) -> fhe.Circuit

Compile encrypted hinge loss.

Compiles the hinge_loss function into an FHE circuit so that loss can be evaluated completely obliviously.

Example
from concrete_fhe_toolkit.ml.core import compile_hinge_loss

circuit = compile_hinge_loss(min_value=-10, max_value=10)
# Calculates max(0, 1 - (y_true * y_pred)) under encryption

Parameters:

Name Type Description Default
min_value int

The lower bound for the encrypted inputs, used to dimension the FHE circuit.

-15
max_value int

The upper bound for the encrypted inputs, used to dimension the FHE circuit.

15
configuration Optional[Configuration]

Optional FHE compiler configuration object.

None

Returns:

Type Description
Circuit

fhe.Circuit: The compiled circuit.

Source code in src/concrete_fhe_toolkit/ml/core.py
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
def compile_hinge_loss(
    min_value: int = -15,
    max_value: int = 15,
    *,
    configuration: Optional[fhe.Configuration] = None,
) -> fhe.Circuit:
    """Compile encrypted hinge loss.

    Compiles the `hinge_loss` function into an FHE circuit so that loss 
    can be evaluated completely obliviously.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import compile_hinge_loss

        circuit = compile_hinge_loss(min_value=-10, max_value=10)
        # Calculates max(0, 1 - (y_true * y_pred)) under encryption
        ```

    Args:
        min_value (int): The lower bound for the encrypted inputs, used to dimension the FHE circuit.
        max_value (int): The upper bound for the encrypted inputs, used to dimension the FHE circuit.
        configuration (Optional[fhe.Configuration]): Optional FHE compiler configuration object.

    Returns:
        fhe.Circuit: The compiled circuit.
    """
    minimum_val, maximum_val = validate_bounds(min_value, max_value)
    return compile_function(
        hinge_loss,
        {"y_pred": "encrypted", "y_true": "encrypted"},
        [
            (minimum_val, minimum_val),
            (minimum_val, maximum_val),
            (maximum_val, minimum_val),
            (maximum_val, maximum_val),
        ],
        configuration,
    )

make_cross_entropy_loss

make_cross_entropy_loss(min_input: int = -127, max_input: int = 128, *, input_scale: int = 100, output_scale: int = 100) -> Callable[[Union[np.ndarray, List[Any]], Union[np.ndarray, List[Any]]], Any]

Create a scaled Binary Cross-Entropy loss function.

This factory creates a cross-entropy function using a pre-configured logarithm table (TLU). The probabilities should be scaled integers.

Example
from concrete_fhe_toolkit.ml.core import make_cross_entropy_loss

cross_entropy = make_cross_entropy_loss(min_input=1, max_input=100)
# Inside an FHE circuit
# loss = cross_entropy(enc_preds, enc_labels)

Parameters:

Name Type Description Default
min_input int

The minimum expected value in the input domain.

-127
max_input int

The maximum expected value in the input domain.

128
input_scale int

The fixed-point scaling factor of the input.

100
output_scale int

The desired fixed-point scaling factor for the output.

100

Returns:

Name Type Description
Callable Callable[[Union[ndarray, List[Any]], Union[ndarray, List[Any]]], Any]

The cross entropy loss function.

Source code in src/concrete_fhe_toolkit/ml/core.py
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
def make_cross_entropy_loss(
    min_input: int = -127,
    max_input: int = 128,
    *,
    input_scale: int = 100,
    output_scale: int = 100,
) -> Callable[[Union[np.ndarray, List[Any]],Union[np.ndarray, List[Any]]], Any]:
    """Create a scaled Binary Cross-Entropy loss function.

    This factory creates a cross-entropy function using a pre-configured 
    logarithm table (TLU). The probabilities should be scaled integers.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import make_cross_entropy_loss

        cross_entropy = make_cross_entropy_loss(min_input=1, max_input=100)
        # Inside an FHE circuit
        # loss = cross_entropy(enc_preds, enc_labels)
        ```

    Args:
        min_input (int): The minimum expected value in the input domain.
        max_input (int): The maximum expected value in the input domain.
        input_scale (int): The fixed-point scaling factor of the input.
        output_scale (int): The desired fixed-point scaling factor for the output.

    Returns:
        Callable: The cross entropy loss function.
    """
    warnings.warn(
            "Cross Entropy requires >16-bit TLUs and will likely fail to compile "
            "in the current version of Concrete. Consider evaluating loss on the client side.",
            UserWarning, stacklevel=2
        )
    log_func = make_log(min_input, max_input, input_scale=input_scale, output_scale=output_scale, invalid_result=-999)

    def cross_entropy_loss(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
        """Calculate the cross-entropy loss.

        Args:
            y_preds (Union[np.ndarray, List[Any]]): Predictions.
            y_trues (Union[np.ndarray, List[Any]]): True values.

        Returns:
            Any: The computed loss.
        """
        preds_tensor = _ensure_tensor(y_preds)
        trues_tensor = _ensure_tensor(y_trues)
        preds_log = log_func(preds_tensor)
        minus_preds_log = log_func(input_scale - preds_tensor)
        loss_tensor = -(trues_tensor * preds_log + (1 - trues_tensor) * minus_preds_log)
        return array_sum(loss_tensor) // len(y_trues)

    return cross_entropy_loss 

compile_cross_entropy_loss

compile_cross_entropy_loss(array_size: int, min_value: int = -127, max_value: int = 127, *, input_scale: int = 100, output_scale: int = 100, configuration: Optional[Configuration] = None) -> fhe.Circuit

Compile encrypted cross-entropy loss.

Example
from concrete_fhe_toolkit.ml.core import compile_cross_entropy_loss

circuit = compile_cross_entropy_loss(array_size=2)

Parameters:

Name Type Description Default
array_size int

Size of array.

required
min_value int

The lower bound for the encrypted inputs, used to dimension the FHE circuit.

-127
max_value int

The upper bound for the encrypted inputs, used to dimension the FHE circuit.

127
input_scale int

The fixed-point scaling factor of the input.

100
output_scale int

The desired fixed-point scaling factor for the output.

100
configuration Optional[Configuration]

Optional FHE compiler configuration object.

None

Returns:

Type Description
Circuit

fhe.Circuit: The compiled circuit.

Source code in src/concrete_fhe_toolkit/ml/core.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
def compile_cross_entropy_loss(
    array_size: int,
    min_value: int = -127,
    max_value: int = 127,
    *,
    input_scale: int = 100,
    output_scale: int = 100,
    configuration: Optional[fhe.Configuration] = None,
) -> fhe.Circuit:
    """Compile encrypted cross-entropy loss.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import compile_cross_entropy_loss

        circuit = compile_cross_entropy_loss(array_size=2)
        ```

    Args:
        array_size (int): Size of array.
        min_value (int): The lower bound for the encrypted inputs, used to dimension the FHE circuit.
        max_value (int): The upper bound for the encrypted inputs, used to dimension the FHE circuit.
        input_scale (int): The fixed-point scaling factor of the input.
        output_scale (int): The desired fixed-point scaling factor for the output.
        configuration (Optional[fhe.Configuration]): Optional FHE compiler configuration object.

    Returns:
        fhe.Circuit: The compiled circuit.
    """
    warnings.warn(
        "compile_cross_entropy_loss requires >16-bit TLUs and will likely fail to compile "
        "in the current version of Concrete. Kept for future 32-bit TLU compatibility.",
        UserWarning, stacklevel=2
    )
    function = make_cross_entropy_loss(min_value, max_value, input_scale=input_scale, output_scale=output_scale)
    minimum, maximum = validate_bounds(min_value, max_value)

    return compile_function(
        function,
        {"y_preds": "encrypted", "y_trues": "encrypted"},
        [
            ([minimum] * array_size, [0] * array_size), # preds ve trues
            ([maximum] * array_size, [1] * array_size),
        ],
        configuration,
    )

precision_score

precision_score(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Any

[Client-Side Helper] This function is intended for cleartext evaluation only. Do not compile it with FHE due to Table Lookup limits or list return types.

Do not compile it with FHE due to Table Lookup limits or list return types.

Integer percent precision: TP * 100 // (TP + FP), 0 with no positive predictions.

The encrypted-by-encrypted division uses a multivariate lookup whose cost grows with the count range, so keep sample counts small when this runs under encryption (it is cheap on decrypted predictions).

Example
from concrete_fhe_toolkit.ml.core import precision_score

# Inside an FHE circuit
# precision_pct = precision_score(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
Any Any

Precision score.

Source code in src/concrete_fhe_toolkit/ml/core.py
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
@client_side_helper
def precision_score(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
    """
    [Client-Side Helper] This function is intended for cleartext evaluation only.
    Do not compile it with FHE due to Table Lookup limits or list return types.

    Do not compile it with FHE due to Table Lookup limits or list return types.

    Integer percent precision: TP * 100 // (TP + FP), 0 with no positive predictions.

    The encrypted-by-encrypted division uses a multivariate lookup whose
    cost grows with the count range, so keep sample counts small when this
    runs under encryption (it is cheap on decrypted predictions).

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import precision_score

        # Inside an FHE circuit
        # precision_pct = precision_score(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Any: Precision score.
    """
    divide = make_floor_divide(zero_result=0)
    tp = true_positives(y_preds, y_trues)
    fp = false_positives(y_preds, y_trues)
    return divide(tp * 100, tp + fp)

recall_score

recall_score(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Any

[Client-Side Helper] This function is intended for cleartext evaluation only. Do not compile it with FHE due to Table Lookup limits or list return types.

Integer percent recall: TP * 100 // (TP + FN), 0 with no positive labels.

Example
from concrete_fhe_toolkit.ml.core import recall_score

# Inside an FHE circuit
# recall_pct = recall_score(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
Any Any

Recall score.

Source code in src/concrete_fhe_toolkit/ml/core.py
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
@client_side_helper
def recall_score(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
    """
    [Client-Side Helper] This function is intended for cleartext evaluation only.
    Do not compile it with FHE due to Table Lookup limits or list return types.

    Integer percent recall: TP * 100 // (TP + FN), 0 with no positive labels.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import recall_score

        # Inside an FHE circuit
        # recall_pct = recall_score(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Any: Recall score.
    """
    divide = make_floor_divide(zero_result=0)
    tp = true_positives(y_preds, y_trues)
    fn = false_negatives(y_preds, y_trues)
    return divide(tp * 100, tp + fn)

f1_score

f1_score(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Any

[Client-Side Helper] This function is intended for cleartext evaluation only. Do not compile it with FHE due to Table Lookup limits or list return types.

Integer percent F1: 2 * P * R // (P + R), 0 when both are 0.

Calculates the harmonic mean of precision and recall. Since it relies on encrypted division, keeping sample sizes small is recommended.

Example
from concrete_fhe_toolkit.ml.core import f1_score

# Inside an FHE circuit
# f1_pct = f1_score(enc_binary_preds, enc_binary_labels)

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
Any Any

F1 score.

Source code in src/concrete_fhe_toolkit/ml/core.py
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
@client_side_helper
def f1_score(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
    """
    [Client-Side Helper] This function is intended for cleartext evaluation only.
    Do not compile it with FHE due to Table Lookup limits or list return types.

    Integer percent F1: 2 * P * R // (P + R), 0 when both are 0.

    Calculates the harmonic mean of precision and recall. Since it relies on 
    encrypted division, keeping sample sizes small is recommended.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import f1_score

        # Inside an FHE circuit
        # f1_pct = f1_score(enc_binary_preds, enc_binary_labels)
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Any: F1 score.
    """
    divide = make_floor_divide(zero_result=0)
    precision = precision_score(y_preds, y_trues)
    recall = recall_score(y_preds, y_trues)
    return divide(2 * precision * recall, precision + recall)

r2_score

r2_score(y_preds: Union[ndarray, List[Any]], y_trues: Union[ndarray, List[Any]]) -> Any

[Client-Side Helper] This function is intended for cleartext evaluation only. Do not compile it with FHE due to Table Lookup limits or list return types.

Integer percent R²: 100 - 100 * SS_res // SS_tot.

SS_tot uses the floor mean of y_trues. When SS_tot is zero (constant targets) the result is 0. Like precision/recall, the encrypted-by-encrypted division uses a multivariate lookup — cheap on decrypted values, expensive under encryption for large ranges.

Example
from concrete_fhe_toolkit.ml.core import r2_score

# After decrypting test results
score = r2_score([3, 5, 8], [3, 4, 9])

Parameters:

Name Type Description Default
y_preds Union[ndarray, List[Any]]

Predictions.

required
y_trues Union[ndarray, List[Any]]

True values.

required

Returns:

Name Type Description
Any Any

R2 score.

Source code in src/concrete_fhe_toolkit/ml/core.py
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
@client_side_helper
def r2_score(y_preds: Union[np.ndarray, List[Any]], y_trues: Union[np.ndarray, List[Any]]) -> Any:
    """
    [Client-Side Helper] This function is intended for cleartext evaluation only.
    Do not compile it with FHE due to Table Lookup limits or list return types.

    Integer percent R²: 100 - 100 * SS_res // SS_tot.

    SS_tot uses the floor mean of ``y_trues``. When SS_tot is zero
    (constant targets) the result is 0. Like precision/recall, the
    encrypted-by-encrypted division uses a multivariate lookup — cheap on
    decrypted values, expensive under encryption for large ranges.

    Example:
        ```python
        from concrete_fhe_toolkit.ml.core import r2_score

        # After decrypting test results
        score = r2_score([3, 5, 8], [3, 4, 9])
        ```

    Args:
        y_preds (Union[np.ndarray, List[Any]]): Predictions.
        y_trues (Union[np.ndarray, List[Any]]): True values.

    Returns:
        Any: R2 score.
    """
    divide = make_floor_divide(zero_result=100)
    ss_res = euclidean_distance_squared(y_preds, y_trues)
    mean_true = array_sum(y_trues) // len(y_trues)
    y_trues_tensor = _ensure_tensor(y_trues)
    ss_tot = np.sum((y_trues_tensor - mean_true) ** 2)
    return 100 - divide(100 * ss_res, ss_tot)