diff --git a/nada_numpy/array.py b/nada_numpy/array.py index 5334f8f..8c963a4 100644 --- a/nada_numpy/array.py +++ b/nada_numpy/array.py @@ -948,6 +948,31 @@ def test_shuffle_randomness(vector_size, num_shuffles): return arr + def var(self) -> "NadaArray": + """ + Compute the variable of array elements. + + Returns: + nadaarray: the variance of array elements + """ + + # Compute the mean + m = self.mean() + + # Initialise the sum to 0 + sum = Integer(0) + + # compute (x_i - mean)^2 + + for v in self.inner: + diff = v - m + sum += (diff * diff) + + # compute variance + var = sum / Integer(self.size) + + return NadaArray(np.array([var])) + def __len__(self): """ Overrides the default behavior of returning the length of the object. diff --git a/nada_numpy/funcs.py b/nada_numpy/funcs.py index dc06087..494b6c0 100644 --- a/nada_numpy/funcs.py +++ b/nada_numpy/funcs.py @@ -78,6 +78,7 @@ "gelu", "silu", "shuffle", + "var", ] @@ -1290,3 +1291,18 @@ def test_shuffle_randomness(vector_size, num_shuffles): ``` """ return arr.shuffle() + +def var(array: NadaArray) -> NadaArray: + """ + Computes the variance of the array elements + + args: + array (nadaarray): input array + + returns: + nadaarray: the variance of the array elements + """ + + return array.var() + + diff --git a/tests/nada-tests/nada-project.toml b/tests/nada-tests/nada-project.toml index 6292beb..8449801 100644 --- a/tests/nada-tests/nada-project.toml +++ b/tests/nada-tests/nada-project.toml @@ -200,4 +200,8 @@ prime_size = 128 [[programs]] path = "src/shuffle.py" -prime_size = 128 \ No newline at end of file +prime_size = 128 + +[[programs]] +path = "src/variance.py" +prime_size = 128 diff --git a/tests/nada-tests/src/variance.py b/tests/nada-tests/src/variance.py new file mode 100644 index 0000000..0bb1cac --- /dev/null +++ b/tests/nada-tests/src/variance.py @@ -0,0 +1,16 @@ +from nada_dsl import * +import nada_numpy as na + +def nada_main(): + parties = na.parties(4) + + a = na.array([4], parties[0], "A", SecretInteger) + + a[0] = SecretInteger(Input("A_0", parties[0])) + a[1] = SecretInteger(Input("A_1", parties[1])) + a[2] = SecretInteger(Input("A_2", parties[2])) + a[3] = SecretInteger(Input("A_3", parties[3])) + + var = a.var() + + return na.output(var, parties[1], "my_output") diff --git a/tests/nada-tests/tests/variance.yaml b/tests/nada-tests/tests/variance.yaml new file mode 100644 index 0000000..4e76edd --- /dev/null +++ b/tests/nada-tests/tests/variance.yaml @@ -0,0 +1,9 @@ +--- +program: variance +inputs: + A_0: 3 + A_1: 3 + A_2: 3 + A_3: 3 +expected_outputs: + my_output_0: 0 diff --git a/tests/test_all.py b/tests/test_all.py index 205de46..8edac4e 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -57,6 +57,7 @@ "shuffle", "array_comparison", "private_inverse", + "var", ] EXAMPLES = [