sampling
This module contains multiple generation functions for sampling a domain. All
use (and return) a random stream in persis_info
, given by the allocation
function.
- sampling.latin_hypercube_sample(H, persis_info, gen_specs, _)
Generates
gen_specs['user']['gen_batch_size']
points in a Latin hypercube sample over the domain defined bygen_specs['user']['ub']
andgen_specs['user']['lb']
.See also
test_1d_sampling.py # noqa
- sampling.uniform_random_sample(H, persis_info, gen_specs, _)
Generates
gen_specs['user']['gen_batch_size']
points uniformly over the domain defined bygen_specs['user']['ub']
andgen_specs['user']['lb']
.See also
test_uniform_sampling.py # noqa
- sampling.uniform_random_sample_cancel(H, persis_info, gen_specs, _)
Similar to uniform_random_sample but with immediate cancellation of selected points for testing.
- sampling.uniform_random_sample_obj_components(H, persis_info, gen_specs, _)
Generates points uniformly over the domain defined by
gen_specs['user']['ub']
andgen_specs['user']['lb']
but requests eachobj_component
be evaluated separately.See also
- sampling.uniform_random_sample_with_var_priorities_and_resources(H, persis_info, gen_specs, _)
Generates points uniformly over the domain defined by
gen_specs['user']['ub']
andgen_specs['user']['lb']
. Also, randomly requests a different priority and number of resource sets to be used in the evaluation of the generated points, after the initial batch.This generator is used to test/demonstrate setting of priorities and resource sets.
- sampling.uniform_random_sample_with_variable_resources(H, persis_info, gen_specs, _)
Generates
gen_specs['user']['gen_batch_size']
points uniformly over the domain defined bygen_specs['user']['ub']
andgen_specs['user']['lb']
.Also randomly requests a different number of resource sets to be used in each evaluation.
This generator is used to test/demonstrate setting of resource sets.
- #.. seealso::
#`test_uniform_sampling_with_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_uniform_sampling_with_variable_resources.py>`_ # noqa
sampling.py
1"""
2This module contains multiple generation functions for sampling a domain. All
3use (and return) a random stream in ``persis_info``, given by the allocation
4function.
5"""
6import numpy as np
7
8__all__ = [
9 "uniform_random_sample",
10 "uniform_random_sample_with_variable_resources",
11 "uniform_random_sample_with_var_priorities_and_resources",
12 "uniform_random_sample_obj_components",
13 "latin_hypercube_sample",
14 "uniform_random_sample_cancel",
15]
16
17
18def uniform_random_sample(H, persis_info, gen_specs, _):
19 """
20 Generates ``gen_specs['user']['gen_batch_size']`` points uniformly over the domain
21 defined by ``gen_specs['user']['ub']`` and ``gen_specs['user']['lb']``.
22
23 .. seealso::
24 `test_uniform_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_uniform_sampling.py>`_ # noqa
25 """
26 ub = gen_specs["user"]["ub"]
27 lb = gen_specs["user"]["lb"]
28
29 n = len(lb)
30 b = gen_specs["user"]["gen_batch_size"]
31
32 H_o = np.zeros(b, dtype=gen_specs["out"])
33
34 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
35
36 return H_o, persis_info
37
38
39def uniform_random_sample_with_variable_resources(H, persis_info, gen_specs, _):
40 """
41 Generates ``gen_specs['user']['gen_batch_size']`` points uniformly over the domain
42 defined by ``gen_specs['user']['ub']`` and ``gen_specs['user']['lb']``.
43
44 Also randomly requests a different number of resource sets to be used in each evaluation.
45
46 This generator is used to test/demonstrate setting of resource sets.
47
48 #.. seealso::
49 #`test_uniform_sampling_with_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_uniform_sampling_with_variable_resources.py>`_ # noqa
50 """
51
52 ub = gen_specs["user"]["ub"]
53 lb = gen_specs["user"]["lb"]
54 max_rsets = gen_specs["user"]["max_resource_sets"]
55
56 n = len(lb)
57 b = gen_specs["user"]["gen_batch_size"]
58
59 H_o = np.zeros(b, dtype=gen_specs["out"])
60
61 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
62 H_o["resource_sets"] = persis_info["rand_stream"].integers(1, max_rsets + 1, b)
63
64 # print(f'GEN: H rsets requested: {H_o["resource_sets"]}')
65
66 return H_o, persis_info
67
68
69def uniform_random_sample_with_var_priorities_and_resources(H, persis_info, gen_specs, _):
70 """
71 Generates points uniformly over the domain defined by ``gen_specs['user']['ub']`` and
72 ``gen_specs['user']['lb']``. Also, randomly requests a different priority and number of
73 resource sets to be used in the evaluation of the generated points, after the initial batch.
74
75 This generator is used to test/demonstrate setting of priorities and resource sets.
76
77 """
78 ub = gen_specs["user"]["ub"]
79 lb = gen_specs["user"]["lb"]
80 max_rsets = gen_specs["user"]["max_resource_sets"]
81
82 n = len(lb)
83
84 if len(H) == 0:
85 b = gen_specs["user"]["initial_batch_size"]
86
87 H_o = np.zeros(b, dtype=gen_specs["out"])
88 for i in range(0, b):
89 # x= i*np.ones(n)
90 x = persis_info["rand_stream"].uniform(lb, ub, (1, n))
91 H_o["x"][i] = x
92 H_o["resource_sets"][i] = 1
93 H_o["priority"] = 1
94
95 else:
96 H_o = np.zeros(1, dtype=gen_specs["out"])
97 # H_o['x'] = len(H)*np.ones(n) # Can use a simple count for testing.
98 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub)
99 H_o["resource_sets"] = persis_info["rand_stream"].integers(1, max_rsets + 1)
100 H_o["priority"] = 10 * H_o["resource_sets"]
101 # print('Created sim for {} resource sets'.format(H_o['resource_sets']), flush=True)
102
103 return H_o, persis_info
104
105
106def uniform_random_sample_obj_components(H, persis_info, gen_specs, _):
107 """
108 Generates points uniformly over the domain defined by ``gen_specs['user']['ub']``
109 and ``gen_specs['user']['lb']`` but requests each ``obj_component`` be evaluated
110 separately.
111
112 .. seealso::
113 `test_uniform_sampling_one_residual_at_a_time.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_uniform_sampling_one_residual_at_a_time.py>`_ # noqa
114 """
115 ub = gen_specs["user"]["ub"]
116 lb = gen_specs["user"]["lb"]
117
118 n = len(lb)
119 m = gen_specs["user"]["components"]
120 b = gen_specs["user"]["gen_batch_size"]
121
122 H_o = np.zeros(b * m, dtype=gen_specs["out"])
123 for i in range(0, b):
124 x = persis_info["rand_stream"].uniform(lb, ub, (1, n))
125 H_o["x"][i * m : (i + 1) * m, :] = np.tile(x, (m, 1))
126 H_o["priority"][i * m : (i + 1) * m] = persis_info["rand_stream"].uniform(0, 1, m)
127 H_o["obj_component"][i * m : (i + 1) * m] = np.arange(0, m)
128
129 H_o["pt_id"][i * m : (i + 1) * m] = len(H) // m + i
130
131 return H_o, persis_info
132
133
134def uniform_random_sample_cancel(H, persis_info, gen_specs, _):
135 """
136 Similar to uniform_random_sample but with immediate cancellation of
137 selected points for testing.
138
139 """
140 ub = gen_specs["user"]["ub"]
141 lb = gen_specs["user"]["lb"]
142
143 n = len(lb)
144 b = gen_specs["user"]["gen_batch_size"]
145
146 H_o = np.zeros(b, dtype=gen_specs["out"])
147 for i in range(b):
148 if i % 10 == 0:
149 H_o[i]["cancel_requested"] = True
150
151 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
152
153 return H_o, persis_info
154
155
156def latin_hypercube_sample(H, persis_info, gen_specs, _):
157 """
158 Generates ``gen_specs['user']['gen_batch_size']`` points in a Latin
159 hypercube sample over the domain defined by ``gen_specs['user']['ub']`` and
160 ``gen_specs['user']['lb']``.
161
162 .. seealso::
163 `test_1d_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_1d_sampling.py>`_ # noqa
164 """
165
166 ub = gen_specs["user"]["ub"]
167 lb = gen_specs["user"]["lb"]
168
169 n = len(lb)
170 b = gen_specs["user"]["gen_batch_size"]
171
172 H_o = np.zeros(b, dtype=gen_specs["out"])
173
174 A = lhs_sample(n, b, persis_info["rand_stream"])
175
176 H_o["x"] = A * (ub - lb) + lb
177
178 return H_o, persis_info
179
180
181def lhs_sample(n, k, stream):
182
183 # Generate the intervals and random values
184 intervals = np.linspace(0, 1, k + 1)
185 rand_source = stream.uniform(0, 1, (k, n))
186 rand_pts = np.zeros((k, n))
187 sample = np.zeros((k, n))
188
189 # Add a point uniformly in each interval
190 a = intervals[:k]
191 b = intervals[1:]
192 for j in range(n):
193 rand_pts[:, j] = rand_source[:, j] * (b - a) + a
194
195 # Randomly perturb
196 for j in range(n):
197 sample[:, j] = rand_pts[stream.permutation(k), j]
198
199 return sample
persistent_sampling
- persistent_sampling.batched_history_matching(H, persis_info, gen_specs, libE_info)
Given - sim_f with an input of x with len(x)=n - b, the batch size of points to generate - q<b, the number of best samples to use in the following iteration
Pseudocode: Let (mu, Sigma) denote a mean and covariance matrix initialized to the origin and the identity, respectively.
While true (batch synchronous for now):
Draw b samples x_1, … , x_b from MVN( mu, Sigma) Evaluate f(x_1), … , f(x_b) and determine the set of q x_i whose f(x_i) values are smallest (breaking ties lexicographically) Update (mu, Sigma) based on the sample mean and sample covariance of these q x values.
See also
test_persistent_sampling.py # noqa
- persistent_sampling.persistent_request_shutdown(H, persis_info, gen_specs, libE_info)
This generation function is similar in structure to persistent_uniform, but uses a count to test exiting on a threshold value. This principle can be used with a supporting allocation function (e.g. start_only_persistent) to shutdown an ensemble when a condition is met.
See also
- persistent_sampling.persistent_uniform(H, persis_info, gen_specs, libE_info)
This generation function always enters into persistent mode and returns
gen_specs['initial_batch_size']
uniformly sampled points the first time it is called. Afterwards, it returns the number of points given. This can be used in either a batch or asynchronous mode by adjusting the allocation function.See also
test_persistent_sampling.py # noqa test_persistent_sampling_async.py # noqa
- persistent_sampling.uniform_random_sample_with_variable_resources(H, persis_info, gen_specs, libE_info)
Generates points uniformly over the domain defined by
gen_specs['user']['ub']
andgen_specs['user']['lb']
. Also randomly requests a different number of resource sets to be used in the evaluation of the generated points after the initial batch.See also
persistent_sampling.py
1import numpy as np
2
3from libensemble.message_numbers import STOP_TAG, PERSIS_STOP, FINISHED_PERSISTENT_GEN_TAG, EVAL_GEN_TAG
4from libensemble.tools.persistent_support import PersistentSupport
5
6__all__ = [
7 "persistent_uniform",
8 "uniform_random_sample_with_variable_resources",
9 "persistent_request_shutdown",
10 "batched_history_matching",
11]
12
13
14def persistent_uniform(H, persis_info, gen_specs, libE_info):
15 """
16 This generation function always enters into persistent mode and returns
17 ``gen_specs['initial_batch_size']`` uniformly sampled points the first time it
18 is called. Afterwards, it returns the number of points given. This can be
19 used in either a batch or asynchronous mode by adjusting the allocation
20 function.
21
22 .. seealso::
23 `test_persistent_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_persistent_sampling.py>`_ # noqa
24 `test_persistent_sampling_async.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_persistent_sampling_async.py>`_ # noqa
25 """
26 ub = gen_specs["user"]["ub"]
27 lb = gen_specs["user"]["lb"]
28 n = len(lb)
29 b = gen_specs["user"]["initial_batch_size"]
30 ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
31
32 # Send batches until manager sends stop tag
33 tag = None
34 while tag not in [STOP_TAG, PERSIS_STOP]:
35 H_o = np.zeros(b, dtype=gen_specs["out"])
36 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
37 tag, Work, calc_in = ps.send_recv(H_o)
38 if hasattr(calc_in, "__len__"):
39 b = len(calc_in)
40
41 H_o = None
42 if gen_specs["user"].get("replace_final_fields", 0):
43 # This is only to test libE ability to accept History after a
44 # PERSIS_STOP. This history is returned in Work.
45 H_o = Work
46 H_o["x"] = -1.23
47
48 return H_o, persis_info, FINISHED_PERSISTENT_GEN_TAG
49
50
51def uniform_random_sample_with_variable_resources(H, persis_info, gen_specs, libE_info):
52 """
53 Generates points uniformly over the domain defined by ``gen_specs['user']['ub']`` and
54 ``gen_specs['user']['lb']``. Also randomly requests a different number of resource
55 sets to be used in the evaluation of the generated points after the initial batch.
56
57 .. seealso::
58 `test_uniform_sampling_with_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_uniform_sampling_with_variable_resources.py>`_ # noqa
59 """
60 ub = gen_specs["user"]["ub"]
61 lb = gen_specs["user"]["lb"]
62 n = len(lb)
63 b = gen_specs["user"]["initial_batch_size"]
64 ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
65
66 H_o = np.zeros(b, dtype=gen_specs["out"])
67 for i in range(0, b):
68 # x= i*np.ones(n)
69 x = persis_info["rand_stream"].uniform(lb, ub, (1, n))
70 H_o["x"][i] = x
71 H_o["resource_sets"][i] = 1
72 H_o["priority"] = 1
73
74 # Send batches until manager sends stop tag
75 tag, Work, calc_in = ps.send_recv(H_o)
76 while tag not in [STOP_TAG, PERSIS_STOP]:
77 H_o = np.zeros(b, dtype=gen_specs["out"])
78 # H_o['x'] = len(H)*np.ones(n)
79 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
80 H_o["resource_sets"] = persis_info["rand_stream"].integers(1, gen_specs["user"]["max_resource_sets"] + 1, b)
81 H_o["priority"] = 10 * H_o["resource_sets"]
82 print("Created {} sims, with worker_teams req. of size(s) {}".format(b, H_o["resource_sets"]), flush=True)
83 tag, Work, calc_in = ps.send_recv(H_o)
84
85 if calc_in is not None:
86 b = len(calc_in)
87
88 return H_o, persis_info, FINISHED_PERSISTENT_GEN_TAG
89
90
91def persistent_request_shutdown(H, persis_info, gen_specs, libE_info):
92 """
93 This generation function is similar in structure to persistent_uniform,
94 but uses a count to test exiting on a threshold value. This principle can
95 be used with a supporting allocation function (e.g. start_only_persistent)
96 to shutdown an ensemble when a condition is met.
97
98 .. seealso::
99 `test_persistent_uniform_gen_decides_stop.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_persistent_uniform_gen_decides_stop.py>`_ # noqa
100 """
101 ub = gen_specs["user"]["ub"]
102 lb = gen_specs["user"]["lb"]
103 n = len(lb)
104 b = gen_specs["user"]["initial_batch_size"]
105 shutdown_limit = gen_specs["user"]["shutdown_limit"]
106 f_count = 0
107 ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
108
109 # Send batches until manager sends stop tag
110 tag = None
111 while tag not in [STOP_TAG, PERSIS_STOP]:
112 H_o = np.zeros(b, dtype=gen_specs["out"])
113 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
114 tag, Work, calc_in = ps.send_recv(H_o)
115 if hasattr(calc_in, "__len__"):
116 b = len(calc_in)
117 f_count += b
118 if f_count >= shutdown_limit:
119 print("Reached threshold.", f_count, flush=True)
120 break # End the persistent gen
121
122 return H_o, persis_info, FINISHED_PERSISTENT_GEN_TAG
123
124
125def uniform_nonblocking(H, persis_info, gen_specs, libE_info):
126 """
127 This generation function is designed to test non-blocking receives.
128
129 .. seealso::
130 `test_persistent_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_persistent_sampling.py>`_ # noqa
131
132 """
133 ub = gen_specs["user"]["ub"]
134 lb = gen_specs["user"]["lb"]
135 n = len(lb)
136 b = gen_specs["user"]["initial_batch_size"]
137 ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
138
139 # Send batches until manager sends stop tag
140 tag = None
141 while tag not in [STOP_TAG, PERSIS_STOP]:
142 H_o = np.zeros(b, dtype=gen_specs["out"])
143 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
144 ps.send(H_o)
145
146 received = False
147 spin_count = 0
148 while not received:
149 tag, Work, calc_in = ps.recv(blocking=False)
150 if tag is not None:
151 received = True
152 else:
153 spin_count += 1
154
155 persis_info["spin_count"] = spin_count
156
157 if hasattr(calc_in, "__len__"):
158 b = len(calc_in)
159
160 return H_o, persis_info, FINISHED_PERSISTENT_GEN_TAG
161
162
163def batched_history_matching(H, persis_info, gen_specs, libE_info):
164 """
165 Given
166 - sim_f with an input of x with len(x)=n
167 - b, the batch size of points to generate
168 - q<b, the number of best samples to use in the following iteration
169
170 Pseudocode:
171 Let (mu, Sigma) denote a mean and covariance matrix initialized to the
172 origin and the identity, respectively.
173
174 While true (batch synchronous for now):
175
176 Draw b samples x_1, ... , x_b from MVN( mu, Sigma)
177 Evaluate f(x_1), ... , f(x_b) and determine the set of q x_i whose f(x_i) values are smallest (breaking ties lexicographically)
178 Update (mu, Sigma) based on the sample mean and sample covariance of these q x values.
179
180 .. seealso::
181 `test_persistent_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_persistent_sampling.py>`_ # noqa
182 """
183 lb = gen_specs["user"]["lb"]
184
185 n = len(lb)
186 b = gen_specs["user"]["initial_batch_size"]
187 q = gen_specs["user"]["num_best_vals"]
188 ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
189
190 mu = np.zeros(n)
191 Sigma = np.eye(n)
192 tag = None
193
194 while tag not in [STOP_TAG, PERSIS_STOP]:
195 H_o = np.zeros(b, dtype=gen_specs["out"])
196 H_o["x"] = persis_info["rand_stream"].multivariate_normal(mu, Sigma, b)
197
198 # Send data and get next assignment
199 tag, Work, calc_in = ps.send_recv(H_o)
200 if calc_in is not None:
201 all_inds = np.argsort(calc_in["f"])
202 best_inds = all_inds[:q]
203 mu = np.mean(H_o["x"][best_inds], axis=0)
204 Sigma = np.cov(H_o["x"][best_inds].T)
205
206 return H_o, persis_info, FINISHED_PERSISTENT_GEN_TAG