def computeRT(item_path, xp=np): with open(item_path, 'r') as f: LINES = [line.strip("';\n") for line in f] param = {} for index, args in enumerate(LINES): name = args[:15].replace(" ", "") name = name[:].replace("=", "") val = args[15:] val = xp.asarray(val.strip("[]").split(","), dtype=xp.float64) param[name] = val cam_dir = param["cam_dir"] cam_pos = param["cam_pos"] cam_up = param["cam_up"] z = cam_dir / xp.linalg.norm(cam_dir) x = xp.cross(cam_up, z) x = x / xp.linalg.norm(x) y = xp.cross(z, x) x = xp.expand_dims(x, axis=1) y = xp.expand_dims(y, axis=1) z = xp.expand_dims(z, axis=1) R = xp.concatenate([x, y, z], axis=1) T = xp.expand_dims(cam_pos, axis=1) R_T = xp.concatenate([R, T], axis=1) return R_T
def view_dirs(norm: cp.ndarray) -> cp.ndarray: dir_0 = cp.asarray([-float(norm[1]), float(norm[0]), 0.]) dir_1 = cp.cross(norm, dir_0) dir_0 = unitize(dir_0) * FOV dir_1 = unitize(dir_1) * FOV dirs = cp.tile( unitize(norm) + dir_0 * cp.linspace(-1, 1, RESOLUTION)[..., cp.newaxis], (RESOLUTION, 1)).reshape(RESOLUTION, RESOLUTION, 3) dirs += (dir_1 * cp.linspace(-1, 1, RESOLUTION)[..., cp.newaxis])[:, cp.newaxis] return dirs
def locate_points( mesh_prefix: str = None, pts_prefix: str = None, chunk_size: int = None, bounding_box: dict = None) -> [cp.ndarray, cp.ndarray, cp.ndarray]: # # Load data tris, verts, vert_normals = load_mesh(mesh_prefix) all_pts = load_query_points(pts_prefix) vertices = verts[tris[:, :]] # # Fix common dimensions num_verts = vertices.shape[0] # # Compute static information about # the triangles # # ==================== # EDGE ORDER # [:, 0, :] = v # [:, 1, :] = -u # [:, 2, :] = -w # ==================== edges = cp.roll(vertices, 1, axis=1) - vertices # (p3-p1, p1-p2, p2-p3) # # Correct edge signs and ordering edges[:, 1, :] = edges[:, 1, :] * -1 edges[:, 2, :] = edges[:, 2, :] * -1 edges = cp.roll(edges, 2, axis=1) tmp = edges[:, 1, :].copy() edges[:, 1, :] = edges[:, 2, :] edges[:, 2, :] = tmp # # Compute normals and lengths normals = cp.cross(edges[:, 0], edges[:, 1]) norms = cp.linalg.norm(normals, axis=1) normssq = cp.square(norms) # return _locate_points(all_pts=all_pts, vertices=vertices, edges=edges, normals=normals, norms=norms, normssq=normssq, chunk_size=chunk_size, num_verts=num_verts, tris=tris, vertex_normals=vert_normals, bounding_box=bounding_box)
""" Array API compatible wrapper for :py:func:`np.cross <numpy.cross>`. See its docstring for more information. """ if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: raise TypeError('Only numeric dtypes are allowed in cross') # Note: this is different from np.cross(), which broadcasts if x1.shape != x2.shape: raise ValueError('x1 and x2 must have the same shape') if x1.ndim == 0: raise ValueError('cross() requires arrays of dimension at least 1') # Note: this is different from np.cross(), which allows dimension 2 if x1.shape[axis] != 3: raise ValueError('cross() dimension must equal 3') return Array._new(np.cross(x1._array, x2._array, axis=axis)) def det(x: Array, /) -> Array: """ Array API compatible wrapper for :py:func:`np.linalg.det <numpy.linalg.det>`. See its docstring for more information. """ # Note: the restriction to floating-point dtypes only is different from # np.linalg.det. if x.dtype not in _floating_dtypes: raise TypeError('Only floating-point dtypes are allowed in det') return Array._new(np.linalg.det(x._array))
def evaluate_chunks( results: [cp.ndarray, cp.ndarray, cp.ndarray], # closest triangle, distance, projection all_pts: cp.ndarray = None, vertices: cp.ndarray = None, edges: cp.ndarray = None, edge_norms: cp.ndarray = None, edge_normssq: cp.ndarray = None, normals: cp.ndarray = None, norms: cp.ndarray = None, normssq: cp.ndarray = None, zero_tensor: cp.ndarray = None, one_tensor: cp.ndarray = None, tris: cp.ndarray = None, vertex_normals: cp.ndarray = None, bounding_box: dict = None, chunk_size: int = None, num_verts: int = None) -> None: # # Expand vertex normals if non empty if vertex_normals is not None: vertex_normals = vertex_normals[tris] vertex_normals = cp.tile(cp.expand_dims(vertex_normals, axis=2), (1, 1, chunk_size, 1)) # begin = time.time() # # Load and extend the batch num_chunks = all_pts.shape[0] // chunk_size for i in range(num_chunks): # # Get subset of the query points start_index = i * chunk_size end_index = (i + 1) * chunk_size pts = all_pts[start_index:end_index, :] # # Match the dimensions to those assumed above. # REPEATED REPEATED # [triangle_index, vert_index, querypoint_index, coordinates] pts = cp.tile(cp.expand_dims(pts, axis=(0, 1)), (num_verts, 3, 1, 1)) # # Compute the differences between # vertices on each triangle and the # points of interest # # [triangle_index, vert_index, querypoint_index, coordinates] # =================== # [:,0,:,:] = p - p1 # [:,1,:,:] = p - p2 # [:,2,:,:] = p - p3 diff_vectors = pts - vertices # # Compute alpha, beta, gamma barycentric = cp.empty(diff_vectors.shape) # # gamma = u x (p - p1) barycentric[:, 2, :, :] = cp.cross(edges[:, 0, :, :], diff_vectors[:, 0, :, :]) # beta = (p - p1) x v barycentric[:, 1, :, :] = cp.cross(diff_vectors[:, 0, :, :], edges[:, 1, :, :]) # alpha = w x (p - p2) barycentric[:, 0, :, :] = cp.cross(edges[:, 2, :, :], diff_vectors[:, 1, :, :]) barycentric = cp.divide( cp.sum(cp.multiply(barycentric, normals), axis=3), normssq) # # Test conditions less_than_one = cp.less_equal(barycentric, one_tensor) more_than_zero = cp.greater_equal(barycentric, zero_tensor) # # if 0 <= gamma and gamma <= 1 # and 0 <= beta and beta <= 1 # and 0 <= alpha and alpha <= 1: cond1 = cp.logical_and(less_than_one, more_than_zero) # # if gamma <= 0: cond2 = cp.logical_not(more_than_zero[:, 2, :]) cond2 = cp.tile(cp.expand_dims(cond2, axis=1), (1, 3, 1)) # # if beta <= 0: cond3 = cp.logical_not(more_than_zero[:, 1, :]) cond3 = cp.tile(cp.expand_dims(cond3, axis=1), (1, 3, 1)) # # if alpha <= 0: cond4 = cp.logical_not(more_than_zero[:, 0, :]) cond4 = cp.tile(cp.expand_dims(cond4, axis=1), (1, 3, 1)) # # Get the projections for each case xi = cp.empty(barycentric.shape) barycentric_ext = cp.tile(cp.expand_dims(barycentric, axis=3), (1, 1, 1, 3)) proj = cp.sum(cp.multiply(barycentric_ext, vertices), axis=1) # # if 0 <= gamma and gamma <= 1 # and 0 <= beta and beta <= 1 # and 0 <= alpha and alpha <= 1: xi[cond1] = barycentric[cond1] # # if gamma <= 0: # x = p - p1 # u = p2 - p1 # a = p1 # b = p2 t2 = cp.divide( # # u.dot(x) cp.sum(cp.multiply(edges[:, 0, :, :], diff_vectors[:, 0, :, :]), axis=2), edge_normssq[:, 0]) xi2 = cp.zeros((t2.shape[0], 3, t2.shape[1])) xi2[:, 0, :] = -t2 + 1 xi2[:, 1, :] = t2 # t2 = cp.tile(cp.expand_dims(t2, axis=2), (1, 1, 3)) lz = cp.less(t2, cp.zeros(t2.shape)) go = cp.greater(t2, cp.ones(t2.shape)) proj2 = vertices[:, 0, :, :] + cp.multiply(t2, edges[:, 0, :, :]) proj2[lz] = vertices[:, 0, :, :][lz] proj2[go] = vertices[:, 1, :, :][go] # xi[cond2] = xi2[cond2] proj[cp.swapaxes(cond2, 1, 2)] = proj2[cp.swapaxes(cond2, 1, 2)] # # if beta <= 0: # x = p - p1 # v = p3 - p1 # a = p1 # b = p3 t3 = cp.divide( # # v.dot(x) cp.sum(cp.multiply(edges[:, 1, :, :], diff_vectors[:, 0, :, :]), axis=2), edge_normssq[:, 1]) xi3 = cp.zeros((t3.shape[0], 3, t3.shape[1])) xi3[:, 0, :] = -t3 + 1 xi3[:, 2, :] = t3 # t3 = cp.tile(cp.expand_dims(t3, axis=2), (1, 1, 3)) lz = cp.less(t3, cp.zeros(t3.shape)) go = cp.greater(t3, cp.ones(t3.shape)) proj3 = vertices[:, 0, :, :] + cp.multiply(t3, edges[:, 1, :, :]) proj3[lz] = vertices[:, 0, :, :][lz] proj3[go] = vertices[:, 2, :, :][go] # xi[cond3] = xi3[cond3] proj[cp.swapaxes(cond3, 1, 2)] = proj3[cp.swapaxes(cond3, 1, 2)] # # if alpha <= 0: # y = p - p2 # w = p3 - p2 # a = p2 # b = p3 t4 = cp.divide( # # w.dot(y) cp.sum(cp.multiply(edges[:, 2, :, :], diff_vectors[:, 1, :, :]), axis=2), edge_normssq[:, 2]) xi4 = cp.zeros((t4.shape[0], 3, t4.shape[1])) xi4[:, 1, :] = -t4 + 1 xi4[:, 2, :] = t4 # t4 = cp.tile(cp.expand_dims(t4, axis=2), (1, 1, 3)) lz = cp.less(t4, cp.zeros(t4.shape)) go = cp.greater(t4, cp.ones(t4.shape)) proj4 = vertices[:, 1, :, :] + cp.multiply(t4, edges[:, 2, :, :]) proj4[lz] = vertices[:, 1, :, :][lz] proj4[go] = vertices[:, 2, :, :][go] # xi[cond4] = xi4[cond4] proj[cp.swapaxes(cond4, 1, 2)] = proj4[cp.swapaxes(cond4, 1, 2)] vec_to_point = pts[:, 0, :, :] - proj distances = cp.linalg.norm(vec_to_point, axis=2) # n = "\n" # print(f"{pts[:,0,:,:]=}") # print(f"{proj=}") # print(f"{pts[:,0,:,:] - proj=}") # print(f"{distances=}") min_distances = cp.min(distances, axis=0) closest_triangles = cp.argmin(distances, axis=0) projections = proj[closest_triangles, np.arange(chunk_size), :] # # Distinguish close triangles is_close = cp.isclose(distances, min_distances) # # Determine sign signed_normal = normals[:, 0, :, :] if vertex_normals is not None: signed_normal = cp.sum(vertex_normals.transpose() * xi.transpose(), axis=2).transpose() is_negative = cp.less_equal( cp.sum(cp.multiply(vec_to_point, signed_normal), axis=2), 0.) # # Combine is_close_and_negative = cp.logical_and(is_close, is_negative) # # Determine if inside is_inside = cp.all(cp.logical_or(is_close_and_negative, cp.logical_not(is_close)), axis=0) # # Overwrite the signs of points # that are outside of the box if bounding_box is not None: # # Extract rotation_matrix = cp.asarray(bounding_box['rotation_matrix']) translation_vector = cp.asarray(bounding_box['translation_vector']) size = cp.asarray(bounding_box['size']) # # Transform transformed_pts = cp.dot( all_pts[start_index:end_index, :] - translation_vector, rotation_matrix) # # Determine if outside bbox inside_bbox = cp.all(cp.logical_and( cp.less_equal(0., transformed_pts), cp.less_equal(transformed_pts, size)), axis=1) # # Treat points outside bbox as # being outside of lumen print(f"{inside_bbox=}") is_inside = cp.logical_and(is_inside, inside_bbox) # # Apply sign to indicate whether the distance is # inside or outside the mesh. min_distances[is_inside] = -1 * min_distances[is_inside] # # Emplace results # [triangle_index, vert_index, querypoint_index, coordinates] results[0][start_index:end_index] = closest_triangles results[1][start_index:end_index] = min_distances results[2][start_index:end_index, :] = projections
def cross(self, v: Vec3) -> Vec3: return Vec3(*cp.cross(self.e, v.e))
def llgs(t, m, H_eff): beta = (gamma*hbar*J_mtj)/(2*q_e*M_s*t_mtj) return -(gamma*mu_0)/(1+alpha**2) * cp.cross(m, H_eff) \ - alpha*(gamma*mu_0)/(1+alpha**2) * cp.cross(m, cp.cross(m,H_eff)) \ + beta/(1+alpha**2) * cp.cross(m, cp.cross(m, m_p)) \ + alpha*beta/(1+alpha**2) * cp.cross(m,m_p)
def llgsSmallNoise2(m): return - (v_sd*gamma*mu_0)/(1+alpha**2)*m*I_sf \ + (v_sd*gamma*mu_0)/(1+alpha**2)*cp.cross(m, alpha*m)
def llgsSmallNoise4(m): return -(v_sd*gamma*mu_0)/(1+alpha**2)*cp.cross(m, I_sf+alpha*m)
def cross(self, v): return Vec3(*cp.cross(self.e, v.e))