def whitening(self) -> NumericArray: gpu = self.gpu num_pack = select_num_pack(gpu) precision = \ ensure_consistent_numeric_arrays((self.inv_cov, ), gpu)[0] return num_pack.linalg.cholesky(precision)
def whitened_points(self) -> NumericArray: gpu = self.gpu num_pack = select_num_pack(gpu) points = \ ensure_consistent_numeric_arrays((self.dataset.T, ), gpu)[0] return num_pack.dot(points, self.whitening)
def __init__(self, dataset: NumericArray, bw_method: tp.Optional[tp.Union[CovarianceFactorFunctionType, str, tp.Callable, numbers.Number]] = None, weights: tp.Optional[NumericArray] = None, gpu: bool = False): self._num_pack = select_num_pack(gpu) self._gpu = gpu self.dataset = atleast_2d(asarray(dataset)) if not self.dataset.size > 1: raise ValueError("`dataset` input should have multiple elements.") self.d, self.n = self.dataset.shape if weights is not None: self._weights = atleast_1d(weights).astype(float) self._weights /= np.sum(self._weights) if self.weights.ndim != 1: raise ValueError("`weights` input should be one-dimensional.") if len(self._weights) != self.n: raise ValueError("`weights` input should be of length n") self._neff = 1.0 / np.sum(self._weights**2) else: self._weights = ones(self.n) / self.n self._covariance_factor = self._get_covariance_factor_function_from_bandwidth_type( bw_method) self._compute_covariance()
def generate_data( n: int, gpu: bool) -> tp.Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]: num_pack = select_num_pack(gpu) a = rand_with_dtype([n], dtype=numpy.float32, num_pack=num_pack) b = rand_with_dtype([n], dtype=numpy.float32, num_pack=num_pack) c = rand_with_dtype([n], dtype=numpy.float32, num_pack=num_pack) return a, b, c
def estimate_pi(n: int, gpu: bool = True) -> float: np = select_num_pack(gpu) x = np.random.rand(n) y = np.random.rand(n) in_quarter_circle = (x * x + y * y) <= 1.0 return 4.0 * float(np.mean(in_quarter_circle))
def gaussian_kernel_estimate_vectorized_whitened(whitening: NumericArray, whitened_points: NumericArray, values: NumericArray, xi: NumericArray, norm: float, dtype: np.generic, gpu: bool) -> NumericArray: # print(f'whitened_points.shape = {whitened_points.shape}') # print(f'values.shape = {xi.shape}') # print(f'xi.shape = {xi.shape}') n, m, d = \ _verify_and_get_shape_of_datapoints_datavalues_and_evaluation_points(points=whitened_points, values=values, xi=xi) whitened_points, values, xi, whitening = \ ensure_consistent_numeric_arrays((whitened_points, values, xi, whitening), gpu) num_pack = select_num_pack(gpu) whitened_points = whitened_points.astype(dtype, copy=False) whitened_xi = num_pack.dot(xi, whitening).astype(dtype, copy=False) values = values.astype(dtype, copy=False) # Create the result array and evaluate the weighted sum whitened_points = whitened_points.reshape((n, 1, d)) whitened_xi = whitened_xi.reshape((1, m, d)) residual = whitened_points - whitened_xi arg = residual * residual del residual if d > 1: assert arg.shape == (n, m, d) arg = num_pack.sum(arg, axis=2) else: arg = arg.reshape((n, m)) # print(arg.shape) if not gpu: assert arg.shape == (n, m) arg = num_pack.exp(-0.5 * arg) * norm if not gpu: assert arg.shape == (n, m) # estimate = num_pack.dot(arg.T, values) estimate = (values * arg).sum(axis=0) if estimate.ndim > 1: estimate = estimate.squeeze() if gpu: cd.sync() return estimate
def estimate_pi(n: int, batches: int = 1, gpu: bool = True) -> float: np = select_num_pack(gpu) n_per_batch = math.ceil(n / batches) pi = 0.0 for _ in range(batches): x = rand_with_dtype([n_per_batch], dtype=numpy.float32, num_pack=np) y = rand_with_dtype([n_per_batch], dtype=numpy.float32, num_pack=np) in_quarter_circle = (x * x + y * y) <= 1.0 del x, y pi += 4.0 * float(np.mean(in_quarter_circle)) del in_quarter_circle return pi / batches
def _compute_result_internal(R: int, dimensions: tp.Tuple[int, ...], arguments: tp.List[NumericArrayOrScalar], functions_cpu: tp.Tuple[tp.Callable, ...], functions_gpu: tp.Tuple[tp.Callable, ...], pre_attach: bool, gpu: bool, dtype: np.generic) \ -> NumericArray: """ This function evaluates a sequence of functions with given positional arguments. Each argument is either a scalar or R-dimensional. The result Args: R: the number of replications (this is the length each of the input vectors if they are not scalars) dimensions: The shape of the output (excluding the R replications which are either attached to the beginning (if pre_attach is True) or to the end. arguments: a list of arguments to be passed to the functions to be evaluated functions_cpu: The sequence of functions to be evaluated on the CPU. functions_gpu: The sequence of functions to be evaluated on the GPU. pre_attach: whether to put the replications in the first or the last axis gpu: whether to evaluate on the cpu or the gpu dtype: the dtype of the output array Returns: """ num_pack = select_num_pack(gpu) if gpu: functions = functions_gpu else: functions = functions_cpu n = (np.prod(dimensions)).item() if pre_attach: dimension_index = tuple([R] + list(dimensions)) else: dimension_index = tuple(list(dimensions) + [R]) result = num_pack.zeros(dimension_index, dtype=dtype) for i in range(n): index = tuple(np.unravel_index(i, dimensions, order='F')) function = functions[i] if pre_attach: location_index = tuple([slice(None)] + list(index)) else: location_index = tuple(list(index) + [slice(None)]) evaluated_function = function(*arguments) result[location_index] = evaluated_function return result
def normalization_constant(self) -> float: gpu = self.gpu num_pack = select_num_pack(gpu) return (2 * np.pi)**(-self.d / 2) * num_pack.prod( num_pack.diag(self.whitening))
def gaussian_kernel_estimate_vectorized(points: NumericArray, values: NumericArray, xi: NumericArray, precision: NumericArray, dtype: np.generic, gpu: bool = False) \ -> NumericArray: """ def gaussian_kernel_estimate(points, real[:, :] values, xi, precision) Evaluate a multivariate Gaussian kernel estimate. Parameters ---------- points : array_like with shape (n, d) Data points to estimate from in d dimenions. values : real[:, :] with shape (n, p) Multivariate values associated with the data points. xi : array_like with shape (m, d) Coordinates to evaluate the estimate at in d dimensions. precision : array_like with shape (d, d) Precision matrix for the Gaussian kernel. dtype : the result dtype gpu : whether to compute the gaussian kernel estimate on the gpu Returns ------- estimate : double[:, :] with shape (m, p) Multivariate Gaussian kernel estimate evaluated at the input coordinates. """ num_pack = select_num_pack(gpu) n, m, d = \ _verify_and_get_shape_of_datapoints_datavalues_and_evaluation_points(points=points, values=values, xi=xi) # n = points.shape[0] # # if points.ndim > 1: # d = points.shape[1] # else: # d = 1 # m = xi.shape[0] # # if values.ndim > 1: # p = values.shape[1] # else: # p = 1 # # if p != 1: # raise ValueError('p != 1 is not supported') # # if xi.shape[1] != d: # raise ValueError("points and xi must have same trailing dim") # if precision.shape[0] != d or precision.shape[1] != d: # raise ValueError("precision matrix must match data dims") points, values, xi, precision = \ ensure_consistent_numeric_arrays((points, values, xi, precision), gpu) # Rescale the data whitening = num_pack.linalg.cholesky(precision).astype(dtype, copy=False) points = num_pack.dot(points, whitening).astype(dtype, copy=False) # xi = num_pack.dot(xi, whitening).astype(dtype, copy=False) values = values.astype(dtype, copy=False) # Evaluate the normalisation norm = (2 * np.pi)**(-d / 2) * num_pack.prod(num_pack.diag(whitening)) # # Create the result array and evaluate the weighted sum # points = points.reshape((n, 1, d)) # xi = xi.reshape((1, m, d)) # residual = points - xi # arg = residual * residual # del residual # if d > 1: # assert arg.shape == (n, m, d) # arg = num_pack.sum(arg, axis=2) # else: # arg = arg.reshape((n, m)) # assert arg.shape == (n, m) # arg = num_pack.exp(- 0.5 * arg) * norm # assert arg.shape == (n, m) # # estimate = num_pack.dot(arg.T, values) # # if gpu: # cd.sync() # # return estimate.squeeze() return gaussian_kernel_estimate_vectorized_whitened(whitening=whitening, whitened_points=points, xi=xi, values=values, norm=norm, dtype=dtype, gpu=gpu)
def process_data(a: NumericArray, b: NumericArray, c: NumericArray, gpu: bool): np = select_num_pack(gpu) return (np.sin(a) + np.cos(b)) * np.arctan(c)