def set_comparison_sample_set(self, comparison_sample_set): r""" Sets the comparison sample set for this comparison. :param comparison_sample_set: comparison sample set :type comparison_sample_set: :class:`~bet.sample.sample_set_base` """ if isinstance(comparison_sample_set, samp.sample_set_base): output_dims = [] output_dims.append(comparison_sample_set.get_dim()) if self._right_sample_set is not None: output_dims.append(self._right_sample_set.get_dim()) if self._left_sample_set is not None: output_dims.append(self._left_sample_set.get_dim()) if len(output_dims) == 1: self._comparison_sample_set = comparison_sample_set elif np.all(np.array(output_dims) == output_dims[0]): self._comparison_sample_set = comparison_sample_set else: raise samp.dim_not_matching("dimension of values incorrect") else: raise AttributeError( "Wrong Type: Should be samp.sample_set_base type") # if a new emulation set is provided, forget the comparison evaluation. if self._left_sample_set is not None: self._left_sample_set._comparison_densities = None if self._right_sample_set is not None: self._right_sample_set._comparison_densities = None
def check_dim(self): r""" Checks that dimensions of left and right sample sets match the dimension of the comparison sample set. :rtype: int :returns: dimension """ left_set = self.get_left() right_set = self.get_right() if left_set.get_dim() != right_set.get_dim(): msg = "These sample sets must have the same dimension." raise samp.dim_not_matching(msg) else: dim = left_set.get_dim() il, ir = self.get_ptr_left(), self.get_ptr_right() if (il is not None) and (ir is not None): if len(il) != len(ir): msg = "The pointers have inconsistent sizes." msg += "\nTry running set_ptr_left() [or _right()]" raise samp.dim_not_matching(msg) return dim
def prob_from_discretization_input(disc, set_new): r""" Calculates :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_new}})` from :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_old}})` where :math:`\lambda_{samples_old}` come from an input discretization. :param disc: Discretiztion on which probabilities have already been calculated :type disc: :class:`~bet.sample.discretization` :param set_new: Sample set for which probabilities will be calculated. :type set_new: :class:`~bet.sample.sample_set_base` """ if disc._emulated_input_sample_set is None: logging.warning("Using MC assumption because no emulated points given") em_set = disc._input_sample_set else: em_set = disc._emulated_input_sample_set if em_set._values_local is None: em_set.global_to_local() if em_set._probabilities_local is None: raise AttributeError("Probabilities must be pre-calculated.") # Check dimensions disc.check_nums() num_new = set_new.check_num() if (disc._input_sample_set._dim != set_new._dim): raise samp.dim_not_matching("Dimensions of sets are not equal.") (_, ptr) = set_new.query(em_set._values_local) ptr = ptr.flat[:] # Set up probability vectors prob_new = np.zeros((num_new, )) prob_em = em_set._probabilities_local for i in range(num_new): Itemp = np.equal(ptr, i) Itemp_sum = np.sum(prob_em[Itemp]) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) prob_new[i] = Itemp_sum # Set probabilities set_new.set_probabilities(prob_new) return prob_new
def prob_from_discretization_input(disc, set_new): r""" Calculates :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_new}})` from :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_old}})` where :math:`\lambda_{samples_old}` come from an input discretization. :param disc: Discretiztion on which probabilities have already been calculated :type disc: :class:`~bet.sample.discretization` :param set_new: Sample set for which probabilities will be calculated. :type set_new: :class:`~bet.sample.sample_set_base` """ if disc._emulated_input_sample_set is None: logging.warning("Using MC assumption because no emulated points given") em_set = disc._input_sample_set else: em_set = disc._emulated_input_sample_set if em_set._values_local is None: em_set.global_to_local() if em_set._probabilities_local is None: raise AttributeError("Probabilities must be pre-calculated.") # Check dimensions disc.check_nums() num_new = set_new.check_num() if (disc._input_sample_set._dim != set_new._dim): raise samp.dim_not_matching("Dimensions of sets are not equal.") (_, ptr) = set_new.query(em_set._values_local) ptr = ptr.flat[:] # Set up probability vectors prob_new = np.zeros((num_new,)) prob_em = em_set._probabilities_local for i in range(num_new): Itemp = np.equal(ptr, i) Itemp_sum = np.sum(prob_em[Itemp]) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) prob_new[i] = Itemp_sum # Set probabilities set_new.set_probabilities(prob_new) return prob_new
def prob_from_sample_set(set_old, set_new): r""" Calculates :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_new}})` from :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_old}})` using the MC assumption with respect to set_old. :param set_old: Sample set on which probabilities have already been calculated :type set_old: :class:`~bet.sample.sample_set_base` :param set_new: Sample set for which probabilities will be calculated. :type set_new: :class:`~bet.sample.sample_set_base` """ # Check dimensions set_old.check_num() num_new = set_new.check_num() if (set_old._dim != set_new._dim): raise samp.dim_not_matching("Dimensions of sets are not equal.") # Map old points new sets if set_old._values_local is None: set_old.global_to_local() (_, ptr) = set_new.query(set_old._values_local) ptr = ptr.flat[:] # Set up probability vector prob_new = np.zeros((num_new, )) # Loop over new cells and distribute probability from old for i in range(num_new): Itemp = np.equal(ptr, i) Itemp_sum = np.sum(set_old._probabilities_local[Itemp]) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) prob_new[i] = Itemp_sum # Set probabilities set_new.set_probabilities(prob_new) return prob_new
def prob_from_sample_set(set_old, set_new): r""" Calculates :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_new}})` from :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_old}})` using the MC assumption with respect to set_old. :param set_old: Sample set on which probabilities have already been calculated :type set_old: :class:`~bet.sample.sample_set_base` :param set_new: Sample set for which probabilities will be calculated. :type set_new: :class:`~bet.sample.sample_set_base` """ # Check dimensions set_old.check_num() num_new = set_new.check_num() if (set_old._dim != set_new._dim): raise samp.dim_not_matching("Dimensions of sets are not equal.") # Map old points new sets if set_old._values_local is None: set_old.global_to_local() (_, ptr) = set_new.query(set_old._values_local) ptr = ptr.flat[:] # Set up probability vector prob_new = np.zeros((num_new,)) # Loop over new cells and distribute probability from old for i in range(num_new): Itemp = np.equal(ptr, i) Itemp_sum = np.sum(set_old._probabilities_local[Itemp]) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) prob_new[i] = Itemp_sum # Set probabilities set_new.set_probabilities(prob_new) return prob_new
def check_type(val, data_set=None): """ Add support for different data types that can be passed as keyword arguments. Attempt to infer dimension and set it correctly. """ if isinstance(data_set, samp.discretization): dim = data_set._output_sample_set.get_dim() elif isinstance(data_set, samp.sample_set_base): dim = data_set.get_dim() else: dim = 1 if isinstance(val, float) or isinstance(val, int): val = np.array([val]*dim) elif isinstance(val, list) or isinstance(val, tuple): if len(val) != dim: raise samp.dim_not_matching("Dimension mismatch.") else: val = np.array(val) elif not isinstance(val, collections.Iterable): val = np.array([val]) else: pass return val
def check_type(val, data_set=None): """ Add support for different data types that can be passed as keyword arguments. Attempt to infer dimension and set it correctly. """ if isinstance(data_set, samp.discretization): dim = data_set._output_sample_set.get_dim() elif isinstance(data_set, samp.sample_set_base): dim = data_set.get_dim() else: dim = 1 if isinstance(val, float) or isinstance(val, int): val = np.array([val] * dim) elif isinstance(val, list) or isinstance(val, tuple): if len(val) != dim: raise samp.dim_not_matching("Dimension mismatch.") else: val = np.array(val) elif not isinstance(val, collections.Iterable): val = np.array([val]) else: pass return val
def generate_for_input_set(self, input_sample_set, order=0): """ Generates a surrogate discretization based on the input discretization, for a user-defined input sample set. The output sample set values and error estimates are piecewise polynomially defined over input sample set cells from the input discretization. For order 0, both are piecewise constant. For order 1, values are piecewise linear (assuming Jacobians exist), and error estimates are piecewise constant. :param input_sample_set: input sample set for surrogate discretization :type set_old: :class:`~bet.sample.sample_set_base` :param order: Polynomial order :type order: int :rtype: :class:`~bet.sample.discretization` :returns: discretization defining the surrogate model """ # Check inputs if order not in [0, 1]: msg = "Order must be 0 or 1." raise calculateError.wrong_argument_type(msg) input_sample_set.check_num() if input_sample_set._dim != self.input_disc._input_sample_set._dim: msg = "Dimensions of input sets are not equal." raise sample.dim_not_matching(msg) # Give properties from input discretization. if input_sample_set._domain is None: if self.input_disc._input_sample_set._domain is not None: input_sample_set.set_domain(self.input_disc.\ _input_sample_set._domain) if input_sample_set._p_norm is None: if self.input_disc._input_sample_set._p_norm is not None: input_sample_set.set_p_norm(self.input_disc.\ _input_sample_set._p_norm) # Setup dummy discretizion to get pointers # Assumes Voronoi sample set for now output_sample_set = sample.sample_set(self.input_disc.\ _output_sample_set._dim) self.dummy_disc = self.input_disc.copy() self.dummy_disc.set_emulated_input_sample_set(input_sample_set) self.dummy_disc.set_emulated_ii_ptr(globalize=False) if order == 0: # define new values based on piecewise constants new_values_local = self.input_disc._output_sample_set.\ _values[self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_values_local(new_values_local) elif order == 1: # define new values based on piecewise linears using Jacobians if self.input_disc._input_sample_set._jacobians is None: if self.input_disc._input_sample_set._jacobians_local is None: msg = "The input discretization must" msg += " have jacobians defined." raise calculateError.wrong_argument_type(msg) else: self.input_disc._input_sample_set.local_to_global() jac_local = self.input_disc._input_sample_set._jacobians[\ self.dummy_disc._emulated_ii_ptr_local] diff_local = self.input_disc._input_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] - \ input_sample_set._values_local new_values_local = self.input_disc._output_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] new_values_local += np.einsum('ijk,ik->ij', jac_local, diff_local) output_sample_set.set_values_local(new_values_local) # if they exist, define error estimates with piecewise constants if self.input_disc._output_sample_set._error_estimates is not None: new_ee = self.input_disc._output_sample_set._error_estimates[\ self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_error_estimates_local(new_ee) # create discretization object for the surrogate self.surrogate_discretization = sample.discretization(input_sample_set\ =input_sample_set, output_sample_set=output_sample_set, output_probability_set=self.input_disc._output_probability_set) return self.surrogate_discretization
def generate_for_input_set(self, input_sample_set, order=0): """ Generates a surrogate discretization based on the input discretization, for a user-defined input sample set. The output sample set values and error estimates are piecewise polynomially defined over input sample set cells from the input discretization. For order 0, both are piecewise constant. For order 1, values are piecewise linear (assuming Jacobians exist), and error estimates are piecewise constant. :param input_sample_set: input sample set for surrogate discretization :type set_old: :class:`~bet.sample.sample_set_base` :param order: Polynomial order :type order: int :rtype: :class:`~bet.sample.discretization` :returns: discretization defining the surrogate model """ # Check inputs if order not in [0, 1]: msg = "Order must be 0 or 1." raise calculateError.wrong_argument_type(msg) input_sample_set.check_num() if input_sample_set._dim != self.input_disc._input_sample_set._dim: msg = "Dimensions of input sets are not equal." raise sample.dim_not_matching(msg) # Give properties from input discretization. if input_sample_set._domain is None: if self.input_disc._input_sample_set._domain is not None: input_sample_set.set_domain(self.input_disc.\ _input_sample_set._domain) if input_sample_set._p_norm is None: if self.input_disc._input_sample_set._p_norm is not None: input_sample_set.set_p_norm(self.input_disc.\ _input_sample_set._p_norm) # Setup dummy discretizion to get pointers # Assumes Voronoi sample set for now output_sample_set = sample.sample_set(self.input_disc.\ _output_sample_set._dim) self.dummy_disc = self.input_disc.copy() self.dummy_disc.set_emulated_input_sample_set(input_sample_set) self.dummy_disc.set_emulated_ii_ptr(globalize=False) if order == 0: # define new values based on piecewise constants new_values_local = self.input_disc._output_sample_set.\ _values[self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_values_local(new_values_local) elif order == 1: # define new values based on piecewise linears using Jacobians if self.input_disc._input_sample_set._jacobians is None: if self.input_disc._input_sample_set._jacobians_local is None: msg = "The input discretization must" msg += " have jacobians defined." raise calculateError.wrong_argument_type(msg) else: self.input_disc._input_sample_set.local_to_global() jac_local = self.input_disc._input_sample_set._jacobians[\ self.dummy_disc._emulated_ii_ptr_local] diff_local = self.input_disc._input_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] - \ input_sample_set._values_local new_values_local = self.input_disc._output_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] new_values_local += np.einsum('ijk,ik->ij', jac_local, diff_local) output_sample_set.set_values_local(new_values_local) # if they exist, define error estimates with piecewise constants if self.input_disc._output_sample_set._error_estimates is not None: new_ee = self.input_disc._output_sample_set._error_estimates[\ self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_error_estimates_local(new_ee) # create discretization object for the surrogate self.surrogate_discretization = sample.discretization(input_sample_set\ =input_sample_set, output_sample_set=output_sample_set, output_probability_set=self.input_disc._output_probability_set) return self.surrogate_discretization
def prob_from_sample_set_with_emulated_volumes(set_old, set_new, set_emulate=None): r""" Calculates :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_new}})` from :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_old}})` using a set of emulated points are distributed with respect to the volume measure. :param set_old: Sample set on which probabilities have already been calculated :type set_old: :class:`~bet.sample.sample_set_base` :param set_new: Sample set for which probabilities will be calculated. :type set_new: :class:`~bet.sample.sample_set_base` :param set_emulate: Sample set for volume emulation :type set_emulate: :class:`~bet.sample.sample_set_base` """ if set_emulate is None: logging.warning("Using MC assumption because no emulated points given") return prob_from_sample_set(set_old, set_new) # Check dimensions num_old = set_old.check_num() num_new = set_new.check_num() set_emulate.check_num() if (set_old._dim != set_new._dim) or (set_old._dim != set_emulate._dim): raise samp.dim_not_matching("Dimensions of sets are not equal.") # Localize emulated points if set_emulate._values_local is None: set_emulate.global_to_local() # Map emulated points to old and new sets (_, ptr1) = set_old.query(set_emulate._values_local) (_, ptr2) = set_new.query(set_emulate._values_local) ptr1 = ptr1.flat[:] ptr2 = ptr2.flat[:] # Set up probability vectors prob_new = np.zeros((num_new, )) prob_em = np.zeros((len(ptr1), )) # Loop over old cells and divide probability over emulated cells warn = False for i in range(num_old): if set_old._probabilities[i] > 0.0: Itemp = np.equal(ptr1, i) Itemp_sum = np.sum(Itemp) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) if Itemp_sum > 0: prob_em[Itemp] += set_old._probabilities[i] / float(Itemp_sum) else: warn = True # Warn that some cells have no emulated points in them if warn: msg = "Some old cells have no emulated points in them. " msg += "Renormalizing probability." logging.warning(msg) total_prob = np.sum(prob_em) total_prob = comm.allreduce(total_prob, op=MPI.SUM) prob_em = prob_em / total_prob # Loop over new cells and distribute probability from emulated cells for i in range(num_new): Itemp = np.equal(ptr2, i) Itemp_sum = np.sum(prob_em[Itemp]) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) prob_new[i] = Itemp_sum # Set probabilities set_new.set_probabilities(prob_new) return prob_new
def __init__(self, comparison_sample_set, sample_set_left=None, sample_set_right=None, ptr_left=None, ptr_right=None): #: Left sample set self._left_sample_set = None #: Right sample set self._right_sample_set = None #: Integration/Emulation set :class:`~bet.sample.sample_set_base` self._comparison_sample_set = comparison_sample_set #: Pointer from ``self._comparison_sample_set`` to #: ``self._left_sample_set`` self._ptr_left = ptr_left #: Pointer from ``self._comparison_sample_set`` to #: ``self._right_sample_set`` self._ptr_right = ptr_right #: local integration left ptr for parallelsim self._ptr_left_local = None #: local integration right ptr for parallelism self._ptr_right_local = None #: Domain self._domain = None #: Left sample set density evaluated on emulation set. self._den_left = None #: Right sample set density evaluated on emulation set. self._den_right = None # extract sample set if isinstance(sample_set_left, samp.sample_set_base): # left sample set self._left_sample_set = sample_set_left self._domain = sample_set_left.get_domain() if isinstance(sample_set_right, samp.sample_set_base): # right sample set self._right_sample_set = sample_set_right if self._domain is not None: if not np.allclose(self._domain, sample_set_right._domain): raise samp.domain_not_matching( "Left and Right domains do not match") else: self._domain = sample_set_right.get_domain() # check dimension consistency if isinstance(comparison_sample_set, samp.sample_set_base): self._num_samples = comparison_sample_set.check_num() output_dims = [] output_dims.append(comparison_sample_set.get_dim()) if self._right_sample_set is not None: output_dims.append(self._right_sample_set.get_dim()) if self._left_sample_set is not None: output_dims.append(self._left_sample_set.get_dim()) if len(output_dims) == 1: self._comparison_sample_set = comparison_sample_set elif np.all(np.array(output_dims) == output_dims[0]): self._comparison_sample_set = comparison_sample_set else: raise samp.dim_not_matching("Dimension of values incorrect") if not isinstance(comparison_sample_set.get_domain(), np.ndarray): # domain can be missing if left/right sample sets present if self._left_sample_set is not None: comparison_sample_set.set_domain(self._domain) else: if self._right_sample_set is not None: comparison_sample_set.set_domain(self._domain) else: # no sample sets provided msg = "Must provide at least one set from\n" msg += "\twhich a domain can be inferred." raise AttributeError(msg) else: if (self._left_sample_set is not None) or \ (self._right_sample_set is not None): pass else: raise AttributeError( "Wrong Type: Should be samp.sample_set_base type") if (ptr_left is not None): if len(ptr_left) != self._num_samples: raise AttributeError( "Left pointer length must match comparison set.") if (ptr_right is not None): if not np.allclose(ptr_left.shape, ptr_right.shape): raise AttributeError("Pointers must be of same length.") if (ptr_right is not None): if len(ptr_right) != self._num_samples: raise AttributeError( "Right pointer length must match comparison set.")
def prob_from_sample_set_with_emulated_volumes(set_old, set_new, set_emulate=None): r""" Calculates :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_new}})` from :math:`P_{\Lambda}(\mathcal{V}_{\lambda_{samples_old}})` using a set of emulated points are distributed with respect to the volume measure. :param set_old: Sample set on which probabilities have already been calculated :type set_old: :class:`~bet.sample.sample_set_base` :param set_new: Sample set for which probabilities will be calculated. :type set_new: :class:`~bet.sample.sample_set_base` :param set_emulate: Sample set for volume emulation :type set_emulate: :class:`~bet.sample.sample_set_base` """ if set_emulate is None: logging.warning("Using MC assumption because no emulated points given") return prob_from_sample_set(set_old, set_new) # Check dimensions num_old = set_old.check_num() num_new = set_new.check_num() set_emulate.check_num() if (set_old._dim != set_new._dim) or (set_old._dim != set_emulate._dim): raise samp.dim_not_matching("Dimensions of sets are not equal.") # Localize emulated points if set_emulate._values_local is None: set_emulate.global_to_local() # Map emulated points to old and new sets (_, ptr1) = set_old.query(set_emulate._values_local) (_, ptr2) = set_new.query(set_emulate._values_local) ptr1 = ptr1.flat[:] ptr2 = ptr2.flat[:] # Set up probability vectors prob_new = np.zeros((num_new,)) prob_em = np.zeros((len(ptr1), )) # Loop over old cells and divide probability over emulated cells warn = False for i in range(num_old): if set_old._probabilities[i] > 0.0: Itemp = np.equal(ptr1, i) Itemp_sum = np.sum(Itemp) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) if Itemp_sum > 0: prob_em[Itemp] += set_old._probabilities[i]/float(Itemp_sum) else: warn = True # Warn that some cells have no emulated points in them if warn: msg = "Some old cells have no emulated points in them. " msg += "Renormalizing probability." logging.warning(msg) total_prob = np.sum(prob_em) total_prob = comm.allreduce(total_prob, op=MPI.SUM) prob_em = prob_em/total_prob # Loop over new cells and distribute probability from emulated cells for i in range(num_new): Itemp = np.equal(ptr2, i) Itemp_sum = np.sum(prob_em[Itemp]) Itemp_sum = comm.allreduce(Itemp_sum, op=MPI.SUM) prob_new[i] = Itemp_sum # Set probabilities set_new.set_probabilities(prob_new) return prob_new