Source code for ariane.lib.utils.math
import numpy as np
from scipy import linalg as la, interpolate
from scipy.spatial import distance as dist
[docs]
def map_intervals(bounds_src, bounds_tar):
"""Return function mapping between two intervals."""
a_src, b_src = bounds_src
a_tar, b_tar = bounds_tar
def f_map(x):
return a_tar + ((b_tar-a_tar) / (b_src-a_src)) * (x-a_src)
return f_map
[docs]
def normalizer(a_src, b_src):
"""Return function mapping an interval to (0, 1)."""
return map_intervals((a_src, b_src), (0, 1))
[docs]
def denormalizer(a_src, b_src):
"""Return function mapping (0, 1) to an interval."""
return map_intervals((0, 1), (a_src, b_src))
[docs]
def cartesian_product(*s):
"""Return the cartesian product of a set of sets."""
meshgrid = np.array(np.meshgrid(*s))
return np.transpose([np.ravel(meshgrid_dim)
for meshgrid_dim in meshgrid])
[docs]
def cholesky_update(L, Aij_new, Aii_new):
"""Update a Cholesky decomposition for new entries."""
V = la.solve_triangular(L, Aij_new, lower=True).T
L_ = la.cholesky(Aii_new - V@V.T, lower=True)
return np.vstack((np.hstack((L, np.zeros_like(Aij_new))),
np.hstack((V, L_))))
[docs]
def compute_corner_pairs(*limits):
"""Return all pairs of corner points of a hypercube."""
dim = len(limits)
x_corners = cartesian_product(*limits)
return x_corners[cartesian_product(*[np.arange(2**dim)]*dim)]
[docs]
def make_grid(limits, num):
"""Return a grid in a hyperrectangle with given number(s) of points per dimension."""
limits = np.atleast_2d(limits)
if type(num) is int:
num = len(limits)*[num]
num = np.atleast_1d(num)
assert len(limits) == len(num)
locs_per_dim = [np.linspace(limits[i, 0], limits[i, 1], num=num[i])
for i in range(len(limits))]
return cartesian_product(*locs_per_dim)
[docs]
def rotation_matrix_2d(alpha: float, in_rad=False):
"""Return a 2D matrix rotating a coordinate system by a given angle."""
if not in_rad:
alpha = np.deg2rad(alpha)
c = np.cos(alpha)
s = np.sin(alpha)
return np.array([[c, -s], [s, c]])
[docs]
def normalized_linear_interpolator(x, f, interpolator=interpolate.LinearNDInterpolator,
fill_value=0, x_min=None, x_max=None):
"""Return a linear interpolator interpolating on a normalized (unit) hypercube."""
x = np.asarray(x)
assert len(x) == len(f)
if x_min is None:
x_min = np.min(x, axis=0)
if x_max is None:
x_max = np.max(x, axis=0)
x_min = np.atleast_1d(x_min)
x_max = np.atleast_1d(x_max)
assert np.shape(x)[1] == len(x_min) == len(x_max)
assert np.alltrue(x_min <= x_max)
x_normalizers = [normalizer(x_min[i], x_max[i]) for i in range(len(x_min))]
x_norm = np.transpose([x_normalizers[i](x[:, i]) for i in range(len(x_normalizers))])
interp = interpolator(x_norm, f, fill_value=fill_value)
return lambda x: interp([x_normalizers[i](x[i]) for i in range(len(x_normalizers))])[0]