Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #457 utils.MaxSlice and utils.MinSlice #473

Merged
merged 2 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/rlwe/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func NoiseGaloisKey(gk *GaloisKey, sk *SecretKey, params Parameters) float64 {
return NoiseEvaluationKey(&gk.EvaluationKey, skIn, skOut, params)
}

// NoiseGadgetCiphertext returns the log2 of the standard devaition of the noise of the input gadget ciphertext with respect to the given plaintext, secret-key and parameters.
// NoiseGadgetCiphertext returns the log2 of the standard deviation of the noise of the input gadget ciphertext with respect to the given plaintext, secret-key and parameters.
// The polynomial pt is expected to be in the NTT and Montgomery domain.
func NoiseGadgetCiphertext(gct *GadgetCiphertext, pt ring.Poly, sk *SecretKey, params Parameters) float64 {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func main() {
panic(err)
}

// Generate a random plaintext with values uniformely distributed in [-1, 1] for the real and imaginary part.
// Generate a random plaintext with values uniformly distributed in [-1, 1] for the real and imaginary part.
valuesWant := make([]complex128, params.MaxSlots())
for i := range valuesWant {
valuesWant[i] = sampling.RandComplex128(-1, 1)
Expand Down Expand Up @@ -235,7 +235,7 @@ func main() {
}

// Step 2: Some circuit in the coefficient domain
// Note: the result of SlotsToCoeffs is naturaly given in bit-reversed order
// Note: the result of SlotsToCoeffs is naturally given in bit-reversed order
// In this example, we multiply by the monomial X^{N/2} (which is the imaginary
// unit in the slots domain)
if err = eval.Evaluator.Mul(ciphertext, 1i, ciphertext); err != nil {
Expand Down
26 changes: 18 additions & 8 deletions utils/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,35 @@ func Alias2D[V any](x, y [][]V) bool {

// EqualSlice checks the equality between two slices of comparables.
func EqualSlice[V comparable](a, b []V) (v bool) {
v = true
if len(a) != len(b) {
return false
}
for i := range a {
v = v && (a[i] == b[i])
if a[i] != b[i] {
return false
}
}
return
return true
}

// MaxSlice returns the maximum value in the slice.
func MaxSlice[V constraints.Ordered](slice []V) (max V) {
for _, c := range slice {
max = Max(max, c)
if len(slice) != 0 {
max = slice[0]
for _, c := range slice {
max = Max(max, c)
}
}
return
}

// MinSlice returns the minimum value in the slice.
func MinSlice[V constraints.Ordered](slice []V) (min V) {
for _, c := range slice {
min = Min(min, c)
if len(slice) != 0 {
min = slice[0]
for _, c := range slice {
min = Min(min, c)
}
}
return
}
Expand Down Expand Up @@ -110,7 +120,7 @@ func RotateSlice[V any](s []V, k int) []V {
func RotateSliceAllocFree[V any](s []V, k int, sout []V) {

if len(s) != len(sout) {
panic("cannot RotateUint64SliceAllocFree: s and sout of different lengths")
panic("cannot RotateSliceAllocFree: s and sout of different lengths")
}

if len(s) == 0 {
Expand Down
95 changes: 95 additions & 0 deletions utils/slices_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package utils

import (
"sort"
"testing"

"github.com/stretchr/testify/require"
)

func TestMinSlice(t *testing.T) {
require.Equal(t, 1, MinSlice([]int{1, 2, 3, 4, 5}))
require.Equal(t, 0, MinSlice([]int{5, 4, 3, 2, 0}))
require.Equal(t, -1, MinSlice([]int{-1, 1}))
require.Equal(t, -2, MinSlice([]int{-1, -2}))
}

func TestMaxSlice(t *testing.T) {
require.Equal(t, 5, MaxSlice([]int{1, 2, 3, 4, 5}))
require.Equal(t, 5, MaxSlice([]int{5, 4, 3, 2, 0}))
require.Equal(t, 1, MaxSlice([]int{-1, 1}))
require.Equal(t, -1, MaxSlice([]int{-1, -2}))
}

func TestEqualSlice(t *testing.T) {
require.True(t, EqualSlice([]int{1, 2, 3}, []int{1, 2, 3}))
require.True(t, EqualSlice([]int{-1, -2, -3}, []int{-1, -2, -3}))
require.True(t, EqualSlice([]int{}, []int{}))
require.False(t, EqualSlice([]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 6}))
require.False(t, EqualSlice([]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4}))
}

func TestIsInSlice(t *testing.T) {
require.True(t, IsInSlice(1, []int{1, 2, 3, 4, 5}))
require.True(t, IsInSlice(-5, []int{-1, -2, -3, -4, -5}))
require.False(t, IsInSlice(0, []int{1, 2, 3, 4, 5}))
require.False(t, IsInSlice(6, []int{1, 2, 3, 4, 5}))
}

func TestGetSortedKeys(t *testing.T) {
m := map[int]int{1: 1, 3: 3, 2: 2}
require.Equal(t, []int{1, 2, 3}, GetSortedKeys(m))
m = map[int]int{-1: 1, -3: 3, -2: 2}
require.Equal(t, []int{-3, -2, -1}, GetSortedKeys(m))
}

func TestGetDistincts(t *testing.T) {
actual := GetDistincts([]int{1, 2})
expected := []int{1, 2}
sort.Ints(expected)
sort.Ints(actual)
require.Equal(t, expected, actual)

actual = GetDistincts([]int{1, 2, 3, 1, 2, 3})
expected = []int{1, 2, 3}
sort.Ints(expected)
sort.Ints(actual)
require.Equal(t, expected, actual)

actual = GetDistincts([]int{-1, 1, 1, 1})
expected = []int{-1, 1}
sort.Ints(expected)
sort.Ints(actual)
require.Equal(t, expected, actual)
}

func TestRotateSlice(t *testing.T) {
actual := RotateSlice([]int{1, 2, 3, 4, 5}, 2)
expected := []int{3, 4, 5, 1, 2}
require.Equal(t, expected, actual)

actual = RotateSlice([]int{1, 2, 3, 4, 5}, -2)
expected = []int{4, 5, 1, 2, 3}
require.Equal(t, expected, actual)

actual = RotateSlice([]int{1, 2, 3, 4, 5}, 0)
expected = []int{1, 2, 3, 4, 5}
require.Equal(t, expected, actual)
}

func TestRotateSliceInPlace(t *testing.T) {
slice := []int{1, 2, 3, 4, 5}
RotateSliceInPlace(slice, 2)
expected := []int{3, 4, 5, 1, 2}
require.Equal(t, expected, slice)

slice = []int{1, 2, 3, 4, 5}
RotateSliceInPlace(slice, -2)
expected = []int{4, 5, 1, 2, 3}
require.Equal(t, expected, slice)

slice = []int{1, 2, 3, 4, 5}
RotateSliceInPlace(slice, 0)
expected = []int{1, 2, 3, 4, 5}
require.Equal(t, expected, slice)
}
2 changes: 1 addition & 1 deletion utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func BitReverse64[V uint64 | uint32 | int | int64](index V, bitLen int) uint64 {
return bits.Reverse64(uint64(index)) >> (64 - bitLen)
}

// HammingWeight64 returns the hammingweight if the input value.
// HammingWeight64 returns the hamming weight if the input value.
func HammingWeight64[V uint64 | uint32 | int | int64](x V) V {
y := uint64(x)
y -= (y >> 1) & 0x5555555555555555
Expand Down
Loading