/
utils.py
77 lines (53 loc) · 1.75 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
r"""
A set of utilty functions
"""
from __future__ import (division, print_function, absolute_import,
unicode_literals)
import numpy as np
__all__=['sample_ellipsoidal_surface',
'sample_ellipsoidal_volume']
__author__ = ['Duncan Campbell']
def sample_ellipsoidal_surface(npts, semi_axes):
r"""
return points sampled uniformly on the surface of a hyperellipsoid
Parameters
----------
npts : int
number of points to sample
semi_axes : array_like
arry of shape (ndim,) of principle semi-axis lengths
Returns
-------
result : numpy.ndarray
array of shape (npts, ndim) of points
"""
semi_axes = np.sort(np.atleast_1d(semi_axes))
ndim = len(semi_axes)
if ndim <= 1:
raise ValueError('hyperellipsoid dimension must be >=2.')
x = np.random.normal(size=(npts,ndim), scale=semi_axes)
r = np.sqrt(np.sum((x/semi_axes)**2, axis=-1))
return (1.0/r[:,np.newaxis])*x
def sample_ellipsoidal_volume(npts, semi_axes):
r"""
return points sampled uniformly within a hyperellipsoidal volume
Parameters
----------
npts : int
number of points to sample
semi_axes : array_like
arry of shape (ndim,) of principle semi-axis lengths
Returns
-------
result : numpy.ndarray
array of shape (npts, ndim) of points
"""
semi_axes = np.sort(np.atleast_1d(semi_axes))[::-1]
ndim = len(semi_axes)
if ndim <= 1:
raise ValueError('hyperellipsoid dimension must be >=2.')
x = np.random.normal(size=(npts,ndim), scale=semi_axes)
r = np.sqrt(np.sum((x/semi_axes)**2, axis=-1))
ran_scale = (np.random.random(npts))**(1.0/ndim)
r = r/ran_scale
return (1.0/r[:,np.newaxis])*x