def __init__( self, X, T, V=None, cache=True, ): from sdot.core.common import is_2d assert is_2d( X ), "This class can only be used for measures supported on 2D domains" self.vertices = X self.triangles = T if V is not None: if isinstance(V, np.ndarray): # TODO raise NotImplementedError else: assert callable(V) self.values_func = V else: self.values_func = lambda x: 1.0 self.cache = cache if self.cache: self.res = {} super().__init__(self.vertices, self.triangles, self.values_func)
def plot_empty_cells(mu, Y, ind, title=""): fig = plt.figure() if is_2d(Y): plot_2d_cloud(Y[ind], fig=fig) plot_2d_tri(mu.vertices, mu.triangles, fig=fig, c="r") else: plot_cloud(Y[ind]) plot_tri(mu.vertices, mu.triangles, fig=fig, c="r") plt.title("{} empty cells{}".format(len(ind), title))
def centroids(self, Y, psi=None): from sdot.core.common import is_2d assert is_2d( Y ), "This class can only be used for measures supported on 2D domains" if psi is None: psi = np.zeros(len(Y)) C = super().centroids(Y, psi) if self.cache: self.res["C"] = C return C
def kantorovich(self, Y, nu, psi=None): from sdot.core.common import is_2d assert is_2d( Y ), "This class can only be used for measures supported on 2D domains" if psi is None: psi = np.zeros(len(Y)) A, DA = super().kantorovich(Y, nu, psi) if self.cache: self.res = {"A": A, "DA": DA} return A, DA
def optimal_transport(self, Y, nu, psi0=None, eps=1e-8, verbose=False, maxit=100): from sdot.core.common import is_2d assert is_2d( Y ), "This class can only be used for measures supported on 2D domains" if psi0 is None: psi0 = np.zeros(len(Y)) psi = super().optimal_transport(Y, nu, psi0, eps, verbose, maxit) return psi
def plot(self, fig=None, as_img=False, colorbar=False): import matplotlib.pyplot as plt fig = fig or plt.figure() if as_img: # Only work with square densities root = math.sqrt(self.values.size) assert int(root + 0.5) ** 2 == self.values.size, "Plot as image only works with square densities" n = int(root) img = self.values.reshape(n, n) plt.imshow(img, interpolation="none") else: from sdot.core.common import plot_2d_tri_func, plot_2d_cloud, plot_tri, plot_cloud, is_2d if is_2d(self.vertices): plot_2d_cloud(self.vertices, cmap=self.values, colorbar=colorbar, fig=fig) # plot_2d_tri_func(self.vertices, self.triangles, self.values, fig=fig) else: plot_cloud(self.vertices, cmap=self.values, colorbar=colorbar, fig=fig)
# Default perturbation parameters : translation, rotation and noise noise_intensity = 0.5 * M vprint("Noise intensity = {}".format(noise_intensity)) cloud = add_noise(cloud, noise_intensity) # noise cloud += 1.0 * np.array([0, 0, 1]) # translation cloud = transform_3d_cloud(rotation_matrix_homogeneous([0, 1, 0], math.pi / 2), cloud) # rotation vprint("Saving initial point cloud to results/icp/initial_{}.xyz".format(target_mesh_basename)) np.savetxt("results/icp/initial_{}.xyz".format(target_mesh_basename), cloud) elif source_ext in [".xyz", ".txt", ".cloud"]: assert os.path.isfile(source_filename), "{} does not exist".format(source_filename) cloud = np.loadtxt(source_filename) if is_2d(cloud): z = np.repeat(0, len(cloud)) cloud = np.hstack((cloud, z.reshape(-1, 1))) elif source_ext in [".off", ".noff", ".coff"]: X, T = io.read_off(source_filename, ignore_prefix=True) cloud, _ = random_in_triangulation(X, T, N) else: raise RuntimeError("Format {} not supported".format(source_ext[1:])) vprint("ICP between {} and {}\n".format(off_file, source_filename)) fig = plt.figure() ax = fig.gca(projection="3d") plot_tri(mesh.vertices, mesh.faces, fig=fig) plot_cloud(cloud, fig=fig) # plt.show()
mu_flat /= mu_flat.sum() nu_flat /= nu_flat.sum() fig = plt.figure() if len(sys.argv) == 1: ax = fig.add_subplot("111", projection="3d") ax.plot_surface(X_mu, Y_mu, mu, color="r") ax.plot_surface(X_nu, Y_nu, nu, color="b") # import matplotlib as mpl # legend1 = mpl.lines.Line2D([0],[0], linestyle="none", c='b', marker='o') # legend2 = mpl.lines.Line2D([0],[0], linestyle="none", c='r', marker='o') # ax.legend([legend1, legend2], ["Source", 'Target'], numpoints = 1) elif len(sys.argv) in [3, 4]: if is_2d(P_mu): plot_2d_cloud(P_mu, fig=fig, cmap="r", labels=["source"]) plot_2d_cloud(P_nu, fig=fig, cmap="b", labels=["target"]) else: plot_cloud(P_mu, fig=fig, cmap="r", labels=["source"]) plot_cloud(P_nu, fig=fig, cmap="b", labels=["target"]) ax = plt.gca() ax.set_aspect("equal") # plt.legend() # plt.show() # plt.imshow(M) # plt.show() # Normal if discrete_init["normal"]:
psi = optimal_transport_3(mu, Y, nu_Y, psi0=psi0, eps=eps, method="newton", maxit=maxit) end_ot = time.time() print("Running time = {}s".format(end_ot - start_ot)) # Results # We can export the Laguerre cells for (Y, psi) as a mesh '/tmp/final_laguerre.obj' that can be opened # with Meshlab for instance mu.export_laguerre_cells(Y, psi=psi, basename="/tmp/final_laguerre") # Now, we plot the dual triangulation (C, T) where C are the centroids of the Laguerre cells C, T = mu.res["C"], mu.res["T"] T = clean_triangulation(C, T) # conforming_centroids_* means that we project the centroids on the boundary # of the triangulated surface if is_2d(X): from sdot.core.optimal_transport_3 import conforming_centroids_2 conforming_C = conforming_centroids_2(mu, C, Y, psi) plot_2d_tri(conforming_C, T) else: from sdot.optimal_transport import conforming_centroids_3 conforming_C = conforming_centroids_3(mu, C, Y, psi) plot_tri(conforming_C, T) plt.show()
nu = lambda y: 1.0 ## Non-uniform # def linear_target(x, a, b, m, M): # alpha = (b - a) / (M - m) # beta = a - alpha * m # return alpha * x + beta # axis = 0 # m, M = np.min(Y[:, axis]), np.max(Y[:, axis]) # # min_nu = 0.1 # fandisk 1k # min_nu = 0.3 # torus 1k # nu = lambda y: linear_target(y[axis], min_nu, 1, m, M) nu = np.apply_along_axis(nu, 1, Y) fig = plt.figure() if is_2d(X): ax = plt.gca() ax.set_aspect("equal") plot_2d_cloud(Y, fig=fig, cmap="b", s=10, labels=["target"]) # plot_2d_hull(X[:, 0:2], fig=fig, c="r") plot_2d_tri(X, T_X, fig=fig, c="r", label="source") else: ax = plt.gca(projection="3d") plot_cloud(Y, ax=ax, fig=fig, cmap="b",labels=["target"], s=15) plot_tri(X, T_X, fig=fig, color="r", label="source") # plt.legend() plt.show() # TODO ## Local if tests_init["local"]: start_local = time.time()