easyvvuq.sampling.grid_sampler
A grid sampler
Useful for e.g. hyperparameter search. The "vary" dict contains the values that must be considered per (hyper)parameter, for instance:
vary = {"x1": [0.0, 0.5, 0.1],
"x2 = [1, 3],
"x3" = [True, False]}
The sampler will create a tensor grid using all specified 1D parameter values.
1"""A grid sampler 2 3Useful for e.g. hyperparameter search. The "vary" dict contains the values 4that must be considered per (hyper)parameter, for instance: 5 6 vary = {"x1": [0.0, 0.5, 0.1], 7 "x2 = [1, 3], 8 "x3" = [True, False]} 9 10The sampler will create a tensor grid using all specified 1D parameter 11values. 12""" 13 14__author__ = "Wouter Edeling" 15__copyright__ = """ 16 17 Copyright 2018 Robin A. Richardson, David W. Wright 18 19 This file is part of EasyVVUQ 20 21 EasyVVUQ is free software: you can redistribute it and/or modify 22 it under the terms of the Lesser GNU General Public License as published by 23 the Free Software Foundation, either version 3 of the License, or 24 (at your option) any later version. 25 26 EasyVVUQ is distributed in the hope that it will be useful, 27 but WITHOUT ANY WARRANTY; without even the implied warranty of 28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 Lesser GNU General Public License for more details. 30 31 You should have received a copy of the Lesser GNU General Public License 32 along with this program. If not, see <https://www.gnu.org/licenses/>. 33 34""" 35__license__ = "LGPL" 36 37from itertools import product 38import numpy as np 39from .base import BaseSamplingElement # , Vary 40 41 42class Grid_Sampler(BaseSamplingElement, sampler_name="grid_sampler"): 43 44 def __init__(self, vary, count=0): 45 """ 46 Initialize the grid sampler. 47 48 Parameters 49 ---------- 50 vary : dict, or list of dicts 51 A dictionary containing all 1D values for each parameter. For instance 52 vary = {"x1": [0.0, 0.5. 1.0], "x2": [True, False]}. This will 53 create a 2D tensor product of all (x1, x2) parameter combinations. 54 If a list of vary dicts is specified, each vary dict will be treated 55 independently to generate points. These dicts do not have to contain 56 the same parameters. The tensor product points are stored in the 57 'points' list, with one tensor product per vary dict. 58 count : int, optional 59 Internal counter used to count the number of samples that have 60 been executed. The default is 0. 61 62 Returns 63 ------- 64 None. 65 66 """ 67 # allways add vary to list, even if only a single dict is specified 68 if not isinstance(vary, list): 69 vary = [vary] 70 71 self.vary = vary 72 self.count = count 73 self.points = [] 74 75 # make sure all parameters are stored in a list or array, even 76 # if they have only a single value 77 for _vary in vary: 78 for param in _vary.keys(): 79 if not isinstance(_vary[param], list) and not isinstance(_vary[param], np.ndarray): 80 vary[param] = [vary[param]] 81 82 # use dtype=object to allow for multiple different type (float, boolean etc) 83 self.points.append(np.array(list(product(*list(_vary.values()))), dtype=object)) 84 85 # the cumulative sizes of all ensembles generated by the vary dicts 86 self.cumul_sizes = np.cumsum([points.shape[0] for points in self.points]) 87 # add a zero to the beginning (necessary in __next__ subroutine) 88 self.cumul_sizes = np.insert(self.cumul_sizes, 0, 0) 89 90 def is_finite(self): 91 return True 92 93 def n_samples(self): 94 """Returns the number of samples in this sampler. 95 """ 96 # return self.points.shape[0] 97 return self.cumul_sizes[-1] 98 99 def get_param_names(self): 100 """ 101 Get the names of all parameters that were varied. 102 103 Returns 104 ------- 105 param_names : list 106 List of parameter names. 107 108 """ 109 param_names = [] 110 for _vary in self.vary: 111 for name in _vary.keys(): 112 if not name in param_names: 113 param_names.append(name) 114 return param_names 115 116 def __next__(self): 117 """ 118 Return the next sample from the input distributions. 119 120 Raises 121 ------ 122 StopIteration 123 Stop iteration when count >= n_samples. 124 125 Returns 126 ------- 127 run_dict : dict 128 A dictionary with the random input samples, e.g. 129 {'x1': 0.5, 'x2': False}. 130 131 """ 132 if self.count < self.n_samples(): 133 vary_idx = np.where(self.count < self.cumul_sizes[1:])[0][0] 134 run_dict = {} 135 i_par = 0 136 for param_name in self.vary[vary_idx].keys(): 137 sample_idx = self.count - self.cumul_sizes[vary_idx] 138 run_dict[param_name] = self.points[vary_idx][sample_idx][i_par] 139 i_par += 1 140 self.count += 1 141 return run_dict 142 else: 143 raise StopIteration
43class Grid_Sampler(BaseSamplingElement, sampler_name="grid_sampler"): 44 45 def __init__(self, vary, count=0): 46 """ 47 Initialize the grid sampler. 48 49 Parameters 50 ---------- 51 vary : dict, or list of dicts 52 A dictionary containing all 1D values for each parameter. For instance 53 vary = {"x1": [0.0, 0.5. 1.0], "x2": [True, False]}. This will 54 create a 2D tensor product of all (x1, x2) parameter combinations. 55 If a list of vary dicts is specified, each vary dict will be treated 56 independently to generate points. These dicts do not have to contain 57 the same parameters. The tensor product points are stored in the 58 'points' list, with one tensor product per vary dict. 59 count : int, optional 60 Internal counter used to count the number of samples that have 61 been executed. The default is 0. 62 63 Returns 64 ------- 65 None. 66 67 """ 68 # allways add vary to list, even if only a single dict is specified 69 if not isinstance(vary, list): 70 vary = [vary] 71 72 self.vary = vary 73 self.count = count 74 self.points = [] 75 76 # make sure all parameters are stored in a list or array, even 77 # if they have only a single value 78 for _vary in vary: 79 for param in _vary.keys(): 80 if not isinstance(_vary[param], list) and not isinstance(_vary[param], np.ndarray): 81 vary[param] = [vary[param]] 82 83 # use dtype=object to allow for multiple different type (float, boolean etc) 84 self.points.append(np.array(list(product(*list(_vary.values()))), dtype=object)) 85 86 # the cumulative sizes of all ensembles generated by the vary dicts 87 self.cumul_sizes = np.cumsum([points.shape[0] for points in self.points]) 88 # add a zero to the beginning (necessary in __next__ subroutine) 89 self.cumul_sizes = np.insert(self.cumul_sizes, 0, 0) 90 91 def is_finite(self): 92 return True 93 94 def n_samples(self): 95 """Returns the number of samples in this sampler. 96 """ 97 # return self.points.shape[0] 98 return self.cumul_sizes[-1] 99 100 def get_param_names(self): 101 """ 102 Get the names of all parameters that were varied. 103 104 Returns 105 ------- 106 param_names : list 107 List of parameter names. 108 109 """ 110 param_names = [] 111 for _vary in self.vary: 112 for name in _vary.keys(): 113 if not name in param_names: 114 param_names.append(name) 115 return param_names 116 117 def __next__(self): 118 """ 119 Return the next sample from the input distributions. 120 121 Raises 122 ------ 123 StopIteration 124 Stop iteration when count >= n_samples. 125 126 Returns 127 ------- 128 run_dict : dict 129 A dictionary with the random input samples, e.g. 130 {'x1': 0.5, 'x2': False}. 131 132 """ 133 if self.count < self.n_samples(): 134 vary_idx = np.where(self.count < self.cumul_sizes[1:])[0][0] 135 run_dict = {} 136 i_par = 0 137 for param_name in self.vary[vary_idx].keys(): 138 sample_idx = self.count - self.cumul_sizes[vary_idx] 139 run_dict[param_name] = self.points[vary_idx][sample_idx][i_par] 140 i_par += 1 141 self.count += 1 142 return run_dict 143 else: 144 raise StopIteration
Baseclass for all EasyVVUQ sampling elements.
Attributes
- sampler_name (str): Name of the particular sampler.
Grid_Sampler(vary, count=0)
45 def __init__(self, vary, count=0): 46 """ 47 Initialize the grid sampler. 48 49 Parameters 50 ---------- 51 vary : dict, or list of dicts 52 A dictionary containing all 1D values for each parameter. For instance 53 vary = {"x1": [0.0, 0.5. 1.0], "x2": [True, False]}. This will 54 create a 2D tensor product of all (x1, x2) parameter combinations. 55 If a list of vary dicts is specified, each vary dict will be treated 56 independently to generate points. These dicts do not have to contain 57 the same parameters. The tensor product points are stored in the 58 'points' list, with one tensor product per vary dict. 59 count : int, optional 60 Internal counter used to count the number of samples that have 61 been executed. The default is 0. 62 63 Returns 64 ------- 65 None. 66 67 """ 68 # allways add vary to list, even if only a single dict is specified 69 if not isinstance(vary, list): 70 vary = [vary] 71 72 self.vary = vary 73 self.count = count 74 self.points = [] 75 76 # make sure all parameters are stored in a list or array, even 77 # if they have only a single value 78 for _vary in vary: 79 for param in _vary.keys(): 80 if not isinstance(_vary[param], list) and not isinstance(_vary[param], np.ndarray): 81 vary[param] = [vary[param]] 82 83 # use dtype=object to allow for multiple different type (float, boolean etc) 84 self.points.append(np.array(list(product(*list(_vary.values()))), dtype=object)) 85 86 # the cumulative sizes of all ensembles generated by the vary dicts 87 self.cumul_sizes = np.cumsum([points.shape[0] for points in self.points]) 88 # add a zero to the beginning (necessary in __next__ subroutine) 89 self.cumul_sizes = np.insert(self.cumul_sizes, 0, 0)
Initialize the grid sampler.
Parameters
- vary (dict, or list of dicts): A dictionary containing all 1D values for each parameter. For instance vary = {"x1": [0.0, 0.5. 1.0], "x2": [True, False]}. This will create a 2D tensor product of all (x1, x2) parameter combinations. If a list of vary dicts is specified, each vary dict will be treated independently to generate points. These dicts do not have to contain the same parameters. The tensor product points are stored in the 'points' list, with one tensor product per vary dict.
- count (int, optional): Internal counter used to count the number of samples that have been executed. The default is 0.
Returns
- None.
def
n_samples(self):
94 def n_samples(self): 95 """Returns the number of samples in this sampler. 96 """ 97 # return self.points.shape[0] 98 return self.cumul_sizes[-1]
Returns the number of samples in this sampler.
def
get_param_names(self):
100 def get_param_names(self): 101 """ 102 Get the names of all parameters that were varied. 103 104 Returns 105 ------- 106 param_names : list 107 List of parameter names. 108 109 """ 110 param_names = [] 111 for _vary in self.vary: 112 for name in _vary.keys(): 113 if not name in param_names: 114 param_names.append(name) 115 return param_names
Get the names of all parameters that were varied.
Returns
- param_names (list): List of parameter names.