def updateSublattice(self, sublattice): boltzmanFactor = np.exp(2 * self.interactionEnergies / (self.k * self.t)) evenDist = np.random.uniform(0, 1, size=self.spec) temp1 = np.greater(self.interactionEnergies, self.ground) temp2 = np.greater(boltzmanFactor, evenDist) criteria = np.logical_and(sublattice, np.logical_or(temp1, temp2)) self.system = np.where(criteria, -self.system, self.system) self.updateEnergies()
def greater(x1: Array, x2: Array, /) -> Array: """ Array API compatible wrapper for :py:func:`np.greater <numpy.greater>`. 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 greater") # Call result type here just to raise on disallowed type combinations _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(np.greater(x1._array, x2._array))
def __gt__(self, other): return cupy.greater(self, other)
def _hc(k, cs, rho, omega): return (cs / sin(omega) * (rho**k) * sin(omega * (k + 1)) * greater(k, -1))
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 basis_pursuit(A, b, tol=1e-4, niter=100, biter=32): """ solves min |x|_1 s.t. Ax=b using a Primal-Dual Interior Point Method Args: A: design matrix of size (d, n) b: measurement vector of length d tol: solver tolerance niter: maximum length of central path biter: maximum number of steps in backtracking line search Returns: vector of length n """ A = cp.asarray(A) b = cp.asarray(b) d, n = A.shape alpha = 0.01 beta = 0.5 mu = 10 e = cp.ones(n) gradf0 = cp.hstack([cp.zeros(n), e]) x = (A.T).dot(inv(A.dot(A.T))).dot(b) absx = cp.abs(x) u = 0.95 * absx + 0.1 * cp.max(absx) fu1 = x - u fu2 = -x - u lamu1 = -1.0 / fu1 lamu2 = -1.0 / fu2 v = A.dot(lamu2 - lamu1) ATv = (A.T).dot(v) sdg = -(cp.inner(fu1, lamu1) + cp.inner(fu2, lamu2)) tau = 2.0 * n * mu / sdg ootau = 1.0 / tau rcent = cp.hstack([-lamu1 * fu1, -lamu2 * fu2]) - ootau rdual = gradf0 + cp.hstack([lamu1 - lamu2 + ATv, -lamu1 - lamu2]) rpri = A.dot(x) - b resnorm = cp.sqrt(norm(rdual)**2 + norm(rcent)**2 + norm(rpri)**2) rdp = cp.empty(2 * n) rcp = cp.empty(2 * n) for i in range(niter): oofu1 = 1.0 / fu1 oofu2 = 1.0 / fu2 w1 = -ootau * (oofu2 - oofu1) - ATv w2 = -1.0 - ootau * (oofu1 + oofu2) w3 = -rpri lamu1xoofu1 = lamu1 * oofu1 lamu2xoofu2 = lamu2 * oofu2 sig1 = -lamu1xoofu1 - lamu2xoofu2 sig2 = lamu1xoofu1 - lamu2xoofu2 sigx = sig1 - sig2**2 / sig1 if cp.min(cp.abs(sigx)) == 0.0: break w1p = -(w3 - A.dot(w1 / sigx - w2 * sig2 / (sigx * sig1))) H11p = A.dot((A.T) * (e / sigx)[:, cp.newaxis]) if cp.min(sigx) > 0.0: dv = solve(H11p, w1p) else: dv = solve(H11p, w1p) dx = (w1 - w2 * sig2 / sig1 - (A.T).dot(dv)) / sigx Adx = A.dot(dx) ATdv = (A.T).dot(dv) du = (w2 - sig2 * dx) / sig1 dlamu1 = lamu1xoofu1 * (du - dx) - lamu1 - ootau * oofu1 dlamu2 = lamu2xoofu2 * (dx + du) - lamu2 - ootau * oofu2 s = 1.0 indp = cp.less(dlamu1, 0.0) indn = cp.less(dlamu2, 0.0) if cp.any(indp): s = min(s, cp.min(-lamu1[indp] / dlamu1[indp])) if cp.any(indn): s = min(s, cp.min(-lamu2[indn] / dlamu2[indn])) indp = cp.greater(dx - du, 0.0) indn = cp.greater(-dx - du, 0.0) if cp.any(indp): s = min(s, cp.min(-fu1[indp] / (dx[indp] - du[indp]))) if cp.any(indn): s = min(s, cp.min(-fu2[indn] / (-dx[indn] - du[indn]))) s = 0.99 * s for j in range(biter): xp = x + s * dx up = u + s * du vp = v + s * dv ATvp = ATv + s * ATdv lamu1p = lamu1 + s * dlamu1 lamu2p = lamu2 + s * dlamu2 fu1p = xp - up fu2p = -xp - up rdp[:n] = lamu1p - lamu2p + ATvp rdp[n:] = -lamu1p - lamu2p rdp += gradf0 rcp[:n] = -lamu1p * fu1p rcp[n:] = lamu2p * fu2p rcp -= ootau rpp = rpri + s * Adx s *= beta if (cp.sqrt(norm(rdp)**2 + norm(rcp)**2 + norm(rpp)**2) <= (1 - alpha * s) * resnorm): break else: break x = xp lamu1 = lamu1p lamu2 = lamu2p fu1 = fu1p fu2 = fu2p sdg = -(cp.inner(fu1, lamu1) + cp.inner(fu2, lamu2)) if sdg < tol: return cp.asnumpy(x) u = up v = vp ATv = ATvp tau = 2.0 * n * mu / sdg rpri = rpp rcent[:n] = lamu1 * fu1 rcent[n:] = lamu2 * fu2 ootau = 1.0 / tau rcent -= ootau rdual[:n] = lamu1 - lamu2 + ATv rdual[n:] = -lamu1 + lamu2 rdual += gradf0 resnorm = cp.sqrt(norm(rdual)**2 + norm(rcent)**2 + norm(rpri)**2) return cp.asnumpy(x)