Source code for airfrans.sampling

import numpy as np

[docs]def cell_sampling_2d(seed, cell_points, cell_attr = None): ''' Sample points in a two dimensional cell via parallelogram sampling and triangle interpolation via barycentric coordinates. The vertices have to be ordered in a certain way. Args: seed (int): Seed for the random number generator. cell_points (np.ndarray): Vertices of the 2 dimensional cells. Shape `(N, 4)` for N cells with 4 vertices. cell_attr (np.ndarray, optional): Features of the vertices of the 2 dimensional cells. Shape `(N, 4, k)` for N cells with 4 edges and k features. If given shape `(N, 4)` it will resize it automatically in a `(N, 4, 1)` tensor. Default: ``None`` ''' rng = np.random.default_rng(seed = seed) # Sampling via triangulation of the cell and parallelogram sampling v0, v1 = cell_points[:, 1] - cell_points[:, 0], cell_points[:, 3] - cell_points[:, 0] v2, v3 = cell_points[:, 3] - cell_points[:, 2], cell_points[:, 1] - cell_points[:, 2] a0, a1 = np.abs(np.linalg.det(np.hstack([v0[:, :2], v1[:, :2]]).reshape(-1, 2, 2))), \ np.abs(np.linalg.det(np.hstack([v2[:, :2], v3[:, :2]]).reshape(-1, 2, 2))) p = a0/(a0 + a1) index_triangle = rng.binomial(1, p)[:, None] u = rng.uniform(size = (len(p), 2)) sampled_point = index_triangle*(u[:, 0:1]*v0 + u[:, 1:2]*v1) + (1 - index_triangle)*(u[:, 0:1]*v2 + u[:, 1:2]*v3) sampled_point_mirror = index_triangle*((1 - u[:, 0:1])*v0 + (1 - u[:, 1:2])*v1) + (1 - index_triangle)*((1 - u[:, 0:1])*v2 + (1 - u[:, 1:2])*v3) reflex = (u.sum(axis = 1) > 1) sampled_point[reflex] = sampled_point_mirror[reflex] # Interpolation on a triangle via barycentric coordinates if cell_attr is not None: t0, t1, t2 = np.zeros_like(v0), index_triangle*v0 + (1 - index_triangle)*v2, index_triangle*v1 + (1 - index_triangle)*v3 w = (t1[:, 1] - t2[:, 1])*(t0[:, 0] - t2[:, 0]) + (t2[:, 0] - t1[:, 0])*(t0[:, 1] - t2[:, 1]) w0 = (t1[:, 1] - t2[:, 1])*(sampled_point[:, 0] - t2[:, 0]) + (t2[:, 0] - t1[:, 0])*(sampled_point[:, 1] - t2[:, 1]) w1 = (t2[:, 1] - t0[:, 1])*(sampled_point[:, 0] - t2[:, 0]) + (t0[:, 0] - t2[:, 0])*(sampled_point[:, 1] - t2[:, 1]) w0, w1 = w0/w, w1/w w2 = 1 - w0 - w1 if len(cell_attr.shape) == 2: cell_attr = cell_attr[:, :, None] attr0 = index_triangle*cell_attr[:, 0] + (1 - index_triangle)*cell_attr[:, 2] attr1 = index_triangle*cell_attr[:, 1] + (1 - index_triangle)*cell_attr[:, 1] attr2 = index_triangle*cell_attr[:, 3] + (1 - index_triangle)*cell_attr[:, 3] sampled_attr = w0[:, None]*attr0 + w1[:, None]*attr1 + w2[:, None]*attr2 sampled_point += index_triangle*cell_points[:, 0] + (1 - index_triangle)*cell_points[:, 2] return np.hstack([sampled_point[:, :2], sampled_attr]) if cell_attr is not None else sampled_point[:, :2]
[docs]def cell_sampling_1d(seed, line_points, line_attr = None): ''' Sample points in a one dimensional cell via linear sampling and interpolation. Args: seed (int): Seed for the random number generator. line_points (np.ndarray): Edges of the 1 dimensional cells. Shape `(N, 2)` for N cells with 2 edges. line_attr (np.ndarray, optional): Features of the edges of the 1 dimensional cells. Shape `(N, 2, k)` for N cells with 2 edges and k features. If given shape `(N, 2)` it will resize it automatically in a `(N, 2, 1)` tensor. Default: ``None`` ''' rng = np.random.default_rng(seed = seed) # Linear sampling u = rng.uniform(size = (len(line_points), 1)) sampled_point = u*line_points[:, 0] + (1 - u)*line_points[:, 1] # Linear interpolation if line_attr is not None: if len(line_attr.shape) == 2: line_attr = line_attr[:, :, None] sampled_attr = u*line_attr[:, 0] + (1 - u)*line_attr[:, 1] return np.hstack([sampled_point[:, :2], sampled_attr]) if line_attr is not None else sampled_point[:, :2]