Coverage for moptipy / tests / on_signed_permutations.py: 86%
44 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
1"""Test stuff on signed permutations with repetitions."""
3from typing import Any, Callable, Iterable, cast
5import numpy as np
6from numpy.random import Generator, default_rng
7from pycommons.types import type_error
9from moptipy.api.operators import Op0, Op1
10from moptipy.spaces.signed_permutations import SignedPermutations
11from moptipy.tests.op0 import validate_op0
12from moptipy.tests.op1 import validate_op1
15def signed_permutations_for_tests(
16 perm_filter: Callable[[SignedPermutations], bool] | None = None) \
17 -> Iterable[SignedPermutations]:
18 """
19 Get a sequence of permutations for tests.
21 :param perm_filter: an optional filter to sort out permutations we cannot
22 use for testing
23 :returns: the sequence of SignedPermutations
24 """
25 r = default_rng()
26 pwrs: list[SignedPermutations] = [
27 SignedPermutations.standard(2),
28 SignedPermutations.standard(3),
29 SignedPermutations.standard(4),
30 SignedPermutations.standard(5),
31 SignedPermutations.standard(6),
32 SignedPermutations.standard(12),
33 SignedPermutations.standard(23),
34 SignedPermutations.with_repetitions(2, 2),
35 SignedPermutations.with_repetitions(2, 3),
36 SignedPermutations.with_repetitions(3, 2),
37 SignedPermutations.with_repetitions(3, 3),
38 SignedPermutations.with_repetitions(5, 5),
39 SignedPermutations.with_repetitions(int(r.integers(6, 10)),
40 int(r.integers(2, 7))),
41 SignedPermutations.with_repetitions(int(r.integers(2, 5)),
42 int(r.integers(6, 10))),
43 SignedPermutations.with_repetitions(int(r.integers(130, 500)),
44 int(r.integers(2, 200))),
45 SignedPermutations([1, 1, 1, 1, 1, 5, 5, 3]),
46 SignedPermutations([2, 1, 1, 1, 1, 1])]
47 if perm_filter is not None:
48 if not callable(perm_filter):
49 raise type_error(perm_filter, "perm_filter", None, call=True)
50 pwrs = [p for p in pwrs if perm_filter(p)]
51 r.shuffle(cast("list", pwrs))
52 return pwrs
55def make_signed_permutation_valid(pwr: SignedPermutations) -> \
56 Callable[[Generator, np.ndarray], np.ndarray]:
57 """
58 Create a function that can make permutations with repetitions valid.
60 :param pwr: the permutations
61 :returns: the function
62 """
63 def __make_valid(prnd: Generator, x: np.ndarray, ppp=pwr) -> np.ndarray:
64 np.copyto(x, ppp.blueprint)
65 prnd.shuffle(x)
66 x *= ((2 * prnd.integers(low=0, high=2, size=len(x))) - 1)
67 return x
68 return __make_valid
71def validate_op0_on_1_signed_permutations(
72 op0: Op0 | Callable[[SignedPermutations], Op0],
73 search_space: SignedPermutations,
74 number_of_samples: int | None = None,
75 min_unique_samples: int | Callable[[
76 int, SignedPermutations], int] | None = None) -> None:
77 """
78 Validate the nullary operator on one `SignedPermutations` instance.
80 :param op0: the operator or operator factory
81 :param search_space: the search space
82 :param number_of_samples: the optional number of samples
83 :param min_unique_samples: the optional unique samples
84 """
85 args: dict[str, Any] = {
86 "op0": op0(search_space) if callable(op0) else op0,
87 "search_space": search_space,
88 "make_search_space_element_valid":
89 make_signed_permutation_valid(search_space),
90 }
91 if number_of_samples is not None:
92 args["number_of_samples"] = number_of_samples
93 if min_unique_samples is not None:
94 args["min_unique_samples"] = min_unique_samples
95 validate_op0(**args)
98def validate_op0_on_signed_permutations(
99 op0: Op0 | Callable[[SignedPermutations], Op0],
100 number_of_samples: int | None = None,
101 min_unique_samples: int | Callable[[
102 int, SignedPermutations], int] | None = None,
103 perm_filter: Callable[[SignedPermutations], bool] | None = None) \
104 -> None:
105 """
106 Validate the nullary operator on several `SignedPermutations` instances.
108 :param op0: the operator or operator factory
109 :param number_of_samples: the optional number of samples
110 :param min_unique_samples: the optional unique samples
111 :param perm_filter: an optional filter to sort out permutations we cannot
112 use for testing
113 """
114 for pwr in signed_permutations_for_tests(perm_filter):
115 validate_op0_on_1_signed_permutations(op0, pwr, number_of_samples,
116 min_unique_samples)
119def validate_op1_on_1_signed_permutations(
120 op1: Op1 | Callable[[SignedPermutations], Op1],
121 search_space: SignedPermutations,
122 number_of_samples: int | None = None,
123 min_unique_samples: int | Callable[[
124 int, SignedPermutations], int] | None = None) -> None:
125 """
126 Validate the unary operator on one `SignedPermutations` instance.
128 :param op1: the operator or operator factory
129 :param search_space: the search space
130 :param number_of_samples: the optional number of samples
131 :param min_unique_samples: the optional unique samples
132 """
133 args: dict[str, Any] = {
134 "op1": op1(search_space) if callable(op1) else op1,
135 "search_space": search_space,
136 "make_search_space_element_valid":
137 make_signed_permutation_valid(search_space),
138 }
139 if number_of_samples is not None:
140 args["number_of_samples"] = number_of_samples
141 if min_unique_samples is not None:
142 args["min_unique_samples"] = min_unique_samples
143 validate_op1(**args)
146def validate_op1_on_signed_permutations(
147 op1: Op1 | Callable[[SignedPermutations], Op1],
148 number_of_samples: int | None = None,
149 min_unique_samples: int | Callable[[
150 int, SignedPermutations], int] | None = None,
151 perm_filter: Callable[[SignedPermutations], bool] | None = None) \
152 -> None:
153 """
154 Validate the unary operator on several `SignedPermutations` instances.
156 :param op1: the operator or operator factory
157 :param number_of_samples: the optional number of samples
158 :param min_unique_samples: the optional unique samples
159 :param perm_filter: an optional filter to sort out permutations we cannot
160 use for testing
161 """
162 for pwr in signed_permutations_for_tests(perm_filter):
163 validate_op1_on_1_signed_permutations(op1, pwr, number_of_samples,
164 min_unique_samples)