Coverage for tests/utils/test_utils.py: 100%

41 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-11-16 21:43 +0000

1import math 

2 

3import numpy as np 

4import pytest 

5 

6from geometric_kernels.utils.utils import ( 

7 binary_vectors_and_subsets, 

8 hamming_distance, 

9 log_binomial, 

10) 

11 

12from ..helper import check_function_with_backend 

13 

14 

15@pytest.mark.parametrize("backend", ["numpy", "tensorflow", "torch", "jax"]) 

16def test_hamming_distance(backend): 

17 

18 X = np.array([[1, 0, 1]], dtype=bool) 

19 

20 X2 = np.array([[0, 0, 1]], dtype=bool) 

21 

22 # Check that hamming_distance gives the correct results for the given inputs. 

23 check_function_with_backend(backend, np.array([[1]]), hamming_distance, X, X2) 

24 check_function_with_backend(backend, np.array([[0]]), hamming_distance, X, X) 

25 check_function_with_backend(backend, np.array([[0]]), hamming_distance, X2, X2) 

26 check_function_with_backend(backend, np.array([[1]]), hamming_distance, X2, X) 

27 

28 X = np.asarray( 

29 [ 

30 [0, 0, 0, 1, 0], 

31 [1, 0, 0, 0, 0], 

32 [1, 1, 1, 1, 0], 

33 [1, 1, 1, 1, 1], 

34 [0, 1, 0, 1, 0], 

35 [0, 0, 0, 0, 0], 

36 [0, 0, 0, 0, 0], 

37 [0, 0, 0, 0, 0], 

38 ], 

39 dtype=bool, 

40 ) 

41 

42 X2 = np.asarray( 

43 [ 

44 [1, 1, 1, 0, 0], 

45 [1, 0, 1, 0, 0], 

46 [1, 0, 1, 0, 1], 

47 ], 

48 dtype=bool, 

49 ) 

50 

51 ham_X_X2 = np.asarray( 

52 [ 

53 [4, 3, 4], 

54 [2, 1, 2], 

55 [1, 2, 3], 

56 [2, 3, 2], 

57 [3, 4, 5], 

58 [3, 2, 3], 

59 [3, 2, 3], 

60 [3, 2, 3], 

61 ], 

62 dtype=int, 

63 ) 

64 

65 ham_X_X = np.asarray( 

66 [ 

67 [0, 2, 3, 4, 1, 1, 1, 1], 

68 [2, 0, 3, 4, 3, 1, 1, 1], 

69 [3, 3, 0, 1, 2, 4, 4, 4], 

70 [4, 4, 1, 0, 3, 5, 5, 5], 

71 [1, 3, 2, 3, 0, 2, 2, 2], 

72 [1, 1, 4, 5, 2, 0, 0, 0], 

73 [1, 1, 4, 5, 2, 0, 0, 0], 

74 [1, 1, 4, 5, 2, 0, 0, 0], 

75 ], 

76 dtype=int, 

77 ) 

78 

79 ham_X2_X2 = np.asarray( 

80 [ 

81 [0, 1, 2], 

82 [1, 0, 1], 

83 [2, 1, 0], 

84 ], 

85 dtype=int, 

86 ) 

87 

88 # Check that hamming_distance gives the correct results for more given inputs. 

89 check_function_with_backend(backend, ham_X_X2, hamming_distance, X, X2) 

90 check_function_with_backend(backend, ham_X_X, hamming_distance, X, X) 

91 check_function_with_backend(backend, ham_X2_X2, hamming_distance, X2, X2) 

92 check_function_with_backend(backend, ham_X_X2.T, hamming_distance, X2, X) 

93 

94 

95@pytest.mark.parametrize("n", [0, 1, 2, 3, 4, 5]) 

96def test_log_binomial(n): 

97 for k in range(n + 1): 

98 # Check that log_binomial gives the same result as the log of the 

99 # binomial coefficient (as computed through `math.comb`). 

100 assert np.isclose(np.log(math.comb(n, k)), log_binomial(n, k), atol=1e-10) 

101 

102 

103@pytest.mark.parametrize("d", [0, 1, 2, 3, 5, 10]) 

104def test_binary_vectors_and_subsets(d): 

105 X, subsets = binary_vectors_and_subsets(d) 

106 

107 # Check the returned values have the correct types. 

108 assert isinstance(X, np.ndarray) 

109 assert isinstance(subsets, list) 

110 

111 # Check the returned values have the correct shapes. 

112 assert X.shape == (2**d, d) 

113 assert X.dtype == bool 

114 assert len(subsets) == 2**d 

115 

116 # Check that all x[i, :] are different and that they have ones at the 

117 # positions contained in subsets[i] and only there. 

118 for i in range(2**d): 

119 xi_alt = np.zeros(d, dtype=bool) 

120 assert isinstance(subsets[i], list) 

121 xi_alt[subsets[i]] = True 

122 assert np.all(X[i, :] == xi_alt) 

123 for j in range(i + 1, 2**d): 

124 assert np.any(X[i, :] != X[j, :])