Statistics
array_mean()¶
Computes floor mean. Tests exact divisibility, flooring, zeroes, and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_mean
def test_array_mean(arr):
return array_mean(arr)
compiler = fhe.Compiler(test_array_mean, {"arr": "encrypted"})
inputset = [([2, 4, 6],), ([1, 1, 1],), ([0, 5, 10],), ([0, 0, 0],), ([-2, -4, -6],), ([-1, 1, 0],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([2, 4, 6]) == 4
assert circuit.encrypt_run_decrypt([1, 1, 1]) == 1
assert circuit.encrypt_run_decrypt([0, 5, 10]) == 5
assert circuit.encrypt_run_decrypt([0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-2, -4, -6]) == -4
assert circuit.encrypt_run_decrypt([-1, 1, 0]) == 0
print("array_mean tests passed!")
array_variance()¶
Computes floor variance. Tests zero variance (all same elements), positive variance, zeroes, and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_variance
def test_array_variance(arr):
return array_variance(arr)
compiler = fhe.Compiler(test_array_variance, {"arr": "encrypted"})
inputset = [([2, 4, 6],), ([5, 5, 5],), ([1, 5, 9],), ([0, 0, 0],), ([-2, -4, -6],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([2, 4, 6]) == 2
assert circuit.encrypt_run_decrypt([5, 5, 5]) == 0
assert circuit.encrypt_run_decrypt([1, 5, 9]) == 10
assert circuit.encrypt_run_decrypt([0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-2, -4, -6]) == 2
print("array_variance tests passed!")
array_std()¶
Computes integer standard deviation. Tests zero std, positive std, zeroes and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_std
def test_array_std(arr):
return array_std(arr, min_value=-15, max_value=15)
compiler = fhe.Compiler(test_array_std, {"arr": "encrypted"})
inputset = [([2, 4, 6],), ([5, 5, 5],), ([1, 5, 9],), ([0, 0, 0],), ([-2, -4, -6],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([2, 4, 6]) == 1
assert circuit.encrypt_run_decrypt([5, 5, 5]) == 0
assert circuit.encrypt_run_decrypt([1, 5, 9]) == 3
assert circuit.encrypt_run_decrypt([0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-2, -4, -6]) == 1
print("array_std tests passed!")
array_covariance()¶
Computes covariance of two arrays. Tests identical (positive cov), inverse (negative cov), zeroes, and constants (zero cov).
from concrete import fhe
from concrete_fhe_toolkit.stats import array_covariance
def test_array_covariance(a1, a2):
return array_covariance(a1, a2)
compiler = fhe.Compiler(test_array_covariance, {"a1": "encrypted", "a2": "encrypted"})
inputset = [([1, 2, 3], [1, 2, 3]), ([2, 4, 6], [2, 4, 6]), ([1, 2, 3], [3, 2, 1]), ([5, 5, 5], [1, 2, 3]), ([0, 0, 0], [0, 0, 0]), ([-1, -2, -3], [-1, -2, -3])]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 2, 3], [1, 2, 3]) == 0
assert circuit.encrypt_run_decrypt([2, 4, 6], [2, 4, 6]) == 2
assert circuit.encrypt_run_decrypt([1, 2, 3], [3, 2, 1]) == -1
assert circuit.encrypt_run_decrypt([5, 5, 5], [1, 2, 3]) == 0
assert circuit.encrypt_run_decrypt([0, 0, 0], [0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-1, -2, -3], [-1, -2, -3]) == 0
print("array_covariance tests passed!")
array_max()¶
Finds maximum value. Tests max at different positions, duplicates, zeroes and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_max
def test_array_max(arr):
return array_max(arr)
compiler = fhe.Compiler(test_array_max, {"arr": "encrypted"})
inputset = [([1, 5, 3],), ([7, 7, 7],), ([0, -2, 2],), ([9, 2, 1],), ([0, 0, 0],), ([-1, -5, -3],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 5, 3]) == 5
assert circuit.encrypt_run_decrypt([7, 7, 7]) == 7
assert circuit.encrypt_run_decrypt([0, -2, 2]) == 2
assert circuit.encrypt_run_decrypt([9, 2, 1]) == 9
assert circuit.encrypt_run_decrypt([0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-1, -5, -3]) == -1
print("array_max tests passed!")
array_min()¶
Finds minimum value. Tests min at different positions, duplicates, zeroes and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_min
def test_array_min(arr):
return array_min(arr)
compiler = fhe.Compiler(test_array_min, {"arr": "encrypted"})
inputset = [([1, 5, 3],), ([7, 7, 7],), ([0, -2, 2],), ([3, 2, -5],), ([0, 0, 0],), ([-1, -5, -3],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 5, 3]) == 1
assert circuit.encrypt_run_decrypt([7, 7, 7]) == 7
assert circuit.encrypt_run_decrypt([0, -2, 2]) == -2
assert circuit.encrypt_run_decrypt([3, 2, -5]) == -5
assert circuit.encrypt_run_decrypt([0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-1, -5, -3]) == -5
print("array_min tests passed!")
array_range()¶
Calculates the range (max - min). Tests zero range (all elements equal), positive ranges, zeroes, and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_range
def test_array_range(arr):
return array_range(arr)
compiler = fhe.Compiler(test_array_range, {"arr": "encrypted"})
inputset = [([1, 5, 3],), ([7, 7, 7],), ([-5, 0, 5],), ([0, 0, 0],), ([-10, -5, -2],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 5, 3]) == 4
assert circuit.encrypt_run_decrypt([7, 7, 7]) == 0
assert circuit.encrypt_run_decrypt([-5, 0, 5]) == 10
assert circuit.encrypt_run_decrypt([0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-10, -5, -2]) == 8
print("array_range tests passed!")
array_count_greater()¶
Counts elements strictly greater than threshold. Tests all greater, none greater, some greater, zeroes and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_count_greater
def test_array_count_greater(arr, thresh):
return array_count_greater(arr, thresh)
compiler = fhe.Compiler(test_array_count_greater, {"arr": "encrypted", "thresh": "encrypted"})
inputset = [([1, 5, 3], 2), ([1, 5, 3], 5), ([1, 5, 3], 0), ([2, 2, 2], 2), ([0, 0, 0], 0), ([-1, -5, -3], -4)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 5, 3], 2) == 2
assert circuit.encrypt_run_decrypt([1, 5, 3], 5) == 0
assert circuit.encrypt_run_decrypt([1, 5, 3], 0) == 3
assert circuit.encrypt_run_decrypt([2, 2, 2], 2) == 0
assert circuit.encrypt_run_decrypt([0, 0, 0], 0) == 0
assert circuit.encrypt_run_decrypt([-1, -5, -3], -4) == 2
print("array_count_greater tests passed!")
array_median()¶
Computes median. Tests sorted, unsorted, arrays with duplicates, zeroes, and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_median
def test_array_median(arr):
return array_median(arr, min_value=-15, max_value=15)
compiler = fhe.Compiler(test_array_median, {"arr": "encrypted"})
inputset = [([1, 5, 3, 4],), ([0, 0, 2, 2],), ([4, 3, 2, 1],), ([0, 0, 0, 0],), ([-1, -5, -3, -4],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 5, 3, 4]) == 3
assert circuit.encrypt_run_decrypt([0, 0, 2, 2]) == 1
assert circuit.encrypt_run_decrypt([4, 3, 2, 1]) == 2
assert circuit.encrypt_run_decrypt([0, 0, 0, 0]) == 0
assert circuit.encrypt_run_decrypt([-1, -5, -3, -4]) == -4
print("array_median tests passed!")
array_percentile()¶
Calculates q-th percentile. Tests 0th (min), 50th (median), 100th (max) percentiles, zeroes and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_percentile
def test_array_percentile(arr):
return array_percentile(arr, q=50, min_value=-15, max_value=15)
compiler = fhe.Compiler(test_array_percentile, {"arr": "encrypted"})
inputset = [([1, 5, 3, 4],), ([-1, -5, -3, -4],), ([0, 0, 0, 0],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 5, 3, 4]) == 4
assert circuit.encrypt_run_decrypt([-1, -5, -3, -4]) == -3
assert circuit.encrypt_run_decrypt([0, 0, 0, 0]) == 0
print("array_percentile tests passed!")
array_histogram()¶
Counts occurrences in range. Tests elements within range, out of range, zeroes and negatives.
import numpy as np
from concrete import fhe
from concrete_fhe_toolkit.stats import array_histogram
def test_array_histogram(arr):
return array_histogram(arr, min_value=-5, max_value=5)
compiler = fhe.Compiler(test_array_histogram, {"arr": "encrypted"})
inputset = [([1, 2, 1],), ([2, 2, 2],), ([0, 4, 5],), ([-2, -1, 0],)]
circuit = compiler.compile(inputset)
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([1, 2, 1])[6:9], [2, 1, 0]) # 1, 2, 3
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([2, 2, 2])[6:9], [0, 3, 0])
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([0, 4, 5])[5:11], [1, 0, 0, 0, 1, 1]) # 0, 1, 2, 3, 4, 5
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([-2, -1, 0])[3:6], [1, 1, 1])
print("array_histogram tests passed!")
array_mode()¶
Returns most frequent value. Tests single clear mode, tie cases (returns first match), zeroes and negatives.
from concrete import fhe
from concrete_fhe_toolkit.stats import array_mode
def test_array_mode(arr):
return array_mode(arr, min_value=-5, max_value=5)
compiler = fhe.Compiler(test_array_mode, {"arr": "encrypted"})
inputset = [([1, 2, 2, 3],), ([1, 1, 3, 3],), ([4, 4, 4, 4],), ([-2, -2, -1, -1],), ([0, 0, 0, 0],)]
circuit = compiler.compile(inputset)
assert circuit.encrypt_run_decrypt([1, 2, 2, 3]) == 2
assert circuit.encrypt_run_decrypt([1, 1, 3, 3]) == 1
assert circuit.encrypt_run_decrypt([4, 4, 4, 4]) == 4
assert circuit.encrypt_run_decrypt([-2, -2, -1, -1]) == -2
assert circuit.encrypt_run_decrypt([0, 0, 0, 0]) == 0
print("array_mode tests passed!")
array_normalize()¶
Normalizes array elements. Tests centering arrays around specific means, zeroes, and negatives.
import numpy as np
from concrete import fhe
from concrete_fhe_toolkit.stats import array_normalize
def test_array_normalize(arr, mean):
return array_normalize(arr, mean, scale=10)
compiler = fhe.Compiler(test_array_normalize, {"arr": "encrypted", "mean": "encrypted"})
inputset = [([2, 4, 6], 4), ([0, 0, 0], 0), ([10, 20, 30], 20), ([-2, -4, -6], -4)]
circuit = compiler.compile(inputset)
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([2, 4, 6], 4), [-20, 0, 20])
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([0, 0, 0], 0), [0, 0, 0])
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([10, 20, 30], 20), [-100, 0, 100])
np.testing.assert_array_equal(circuit.encrypt_run_decrypt([-2, -4, -6], -4), [20, 0, -20])
print("array_normalize tests passed!")