def test_1d(self): aa = np.random.uniform(*[-100, 100], 1000) bounds = [-23, 43] print(aa) print(bounds) for out in [False, True]: idx = utils.bound_indices(aa, bounds, outside=out) test_yes = aa[idx] test_not = aa[~idx] print("\n", out, idx) for val, test in zip([out, not out], [test_yes, test_not]): if len(test) == 0: continue outside = (test < bounds[0]) | (bounds[1] < test) inside = (bounds[0] < test) & (test < bounds[1]) print("outside = {}, out = {}, val = {}".format( np.all(outside), out, val)) utils.alltrue(outside == val) print("inside = {}, out = {}, val = {}".format( np.all(inside), out, val)) utils.alltrue(inside == (not val)) return
def _truncate_reflections(self, data, bounds, weights=None): # Determine the bounds outside of which we should truncate trunc = self._get_truncation_bounds(bounds) # Find the data-points outside of those bounds idx = utils.bound_indices(data, trunc) # Select only points within truncation bounds data = data[:, idx] if weights is not None: weights = weights[idx] weights /= np.sum(weights) return data, weights
def _check_reflect(reflect, data, weights=None, helper=False): """Make sure the given `reflect` argument is valid given the data shape """ if reflect is None: return reflect if reflect is False: return None # NOTE: FIX: Should this happen in the method that calls `_check_reflect`? # data = np.atleast_2d(data) # ndim, nval = np.shape(data) data = np.asarray(data) ndim, nval = data.shape if reflect is True: reflect = [True for ii in range(ndim)] if (len(reflect) == 2) and (ndim == 1): reflect = np.atleast_2d(reflect) if (len(reflect) != ndim): # and not ((len(reflect) == 2) and (ndim == 1)): err = "`reflect` ({},) must match the data with shape ({}) parameters!".format( len(reflect), data.shape) raise ValueError(err) try: goods = [(ref is None) or (ref is True) or (len(ref) == 2) for ref in reflect] except TypeError as err: err = "Invalid `reflect` argument: Error: '{}'".format(err) raise ValueError(err) if not np.all(goods): err = "each row of `reflect` must be `None` or have shape (2,)! '{}'".format(reflect) raise ValueError(err) # Perform additional diagnostics for ii in range(ndim): if (reflect[ii] is True): reflect[ii] = [np.min(data[ii])*(1 - _NUM_PAD), np.max(data[ii])*(1 + _NUM_PAD)] elif (reflect[ii] is not None) and (True in reflect[ii]): if reflect[ii][0] is True: reflect[ii][0] = np.min(data[ii])*(1 - _NUM_PAD) if reflect[ii][1] is True: reflect[ii][1] = np.max(data[ii])*(1 + _NUM_PAD) if np.all(np.array(reflect[ii]) != None) and (reflect[ii][0] >= reflect[ii][1]): # noqa err = "Reflect is out of order: `reflect`[{}] = {} !".format(ii, reflect[ii]) raise ValueError(err) if helper: # Warn if any datapoints are outside of reflection bounds bads = utils.bound_indices(data[ii, :], reflect[ii], outside=True) if np.any(bads): if weights is None: frac = np.count_nonzero(bads) / bads.size else: frac = np.sum(weights[bads]) / np.sum(weights) msg = ( "A fraction {:.2e} of data[{}] ".format(frac, ii) + " are outside of `reflect` bounds!" ) logging.warning(msg) msg = ( "`reflect[{}]` = {}; ".format(ii, reflect[ii]) + "`data[{}]` = {}".format(ii, utils.stats_str(data[ii], weights=weights)) ) logging.warning(msg) logging.warning("I hope you know what you're doing.") return reflect
def _resample_reflect(self, data, size, reflect, weights=None, keep=None): """Resample the given data using reflection. """ matrix = self.matrix # Modify covariance-matrix for any `keep` dimensions matrix = utils.cov_keep_vars(matrix, keep, reflect=reflect) ndim, nvals = np.shape(data) # Actually 'reflect' (append new, mirrored points) around the given reflection points # Also construct bounding box for valid data data, bounds, weights = self._reflect_data(data, reflect, weights=weights) # Remove data points outside of kernels (or truncated region) data, weights = self._truncate_reflections(data, bounds, weights=weights) if (self._chunk is not None) and (self._chunk < size): num_chunks = int(np.ceil(size/self._chunk)) chunk_size = int(np.ceil(size/num_chunks)) else: chunk_size = size num_chunks = 1 # Draw randomly from the given data points, proportionally to their weights samps = np.zeros((size, ndim)) num_good = 0 cnt = 0 MAX = 10 draw = chunk_size fracs = [] while (num_good < size) and (cnt < MAX * num_chunks): # Draw candidate resample points # set `keep` to None, `matrix` is already modified to account for it trial = self._resample_clear(data, draw, weights=weights, matrix=matrix, keep=None) # Find the (boolean) indices of values within target boundaries idx = utils.bound_indices(trial, bounds) # Store good values to output array ngd = np.count_nonzero(idx) fracs.append(ngd/idx.size) if num_good + ngd <= size: samps[num_good:num_good+ngd, :] = trial.T[idx, :] else: ngd = (size - num_good) samps[num_good:num_good+ngd, :] = trial.T[idx, :][:ngd] # Increment counters num_good += ngd cnt += 1 # Next time, draw twice as many as we need draw = np.minimum(size - num_good, chunk_size) draw = (2**ndim) * draw draw = np.minimum(draw, int(self._chunk)) if num_good < size: err = "Failed to draw '{}' samples in {} iterations!".format(size, cnt) logging.error("") logging.error(err) logging.error("fracs = {}\n\t{}".format(utils.stats_str(fracs), fracs)) logging.error("Obtained {} samples".format(num_good)) logging.error("Reflect: {}".format(reflect)) logging.error("Bandwidths: {}".format(np.sqrt(self.matrix.diagonal().squeeze()))) logging.error("data = ") for dd in data: logging.error("\t{}".format(utils.stats_str(dd))) raise RuntimeError(err) samps = samps.T return samps
def inside(cls, points): points = np.atleast_2d(points) ndim, nvals = np.shape(points) bounds = [[-1.0, 1.0] for ii in range(ndim)] idx = utils.bound_indices(points, bounds) return idx