def proj_noncongested(points, domain, center=None, mass=None, radial_func=RadialFuncInBall(), verbose=None): nb_points = len(points) assert (nb_points != 0) if mass is None: mass = np.ones(nb_points) / nb_points laguerre = OptimalTransport(positions=points, weights=None, masses=mass, domain=domain, radial_func=radial_func, linear_solver="CuPyx") if not center is None: initialize_weights(power_diagram=laguerre.pd, center=center, verbose=verbose) laguerre.adjust_weights(relax=1) if np.linalg.norm(laguerre.pd.integrals() - mass) > 1e-5: print("The Newton algorithm did not converge!") laguerre.display_vtk("debug_file/bad_Newton.vtk", points=True) laguerre.get_domain().display_boundaries_vtk( "debug_file/bad_Newton_domain.vtk") np.save("debug_file/bad_positions", laguerre.get_positions()) np.save("debug_file/integrals", laguerre.pd.integrals()) np.save("debug_file/bad_weights", laguerre.get_weights()) assert (False) return laguerre.pd
def __init__( self, domain, positions, velocities, masses, base_filename ): self.ot = OptimalTransport(domain, RadialFuncInBall()) self.ot.set_positions(np.array(positions)) self.ot.set_weights(np.array(masses)/np.pi) self.ot.set_masses(np.array(masses)) self.base_filename = base_filename self.cpt_display = 0 self.max_iter = 200 self.time = 0 # initial centroid positions and velocities self.ot.adjust_weights() self.centroids = self.ot.get_centroids() self.velocities = np.array(velocities) self.coeff_centroid_force = 1e-4
def test_ball_cut(self, nb_diracs=100): for _ in range(10): ot = OptimalTransport(self.domain, RadialFuncInBall()) positions = np.random.rand(nb_diracs, 2) positions[:, 1] *= 0.5 radius = 0.25 / nb_diracs**0.5 mass = np.pi * radius**2 # diracs ot.set_positions(positions) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) # optimal weights ot.adjust_weights() # integrals areas = ot.pd.integrals() self.assertAlmostEqual(np.min(areas), mass, places=6) self.assertAlmostEqual(np.max(areas), mass, places=6)
def test_base_ot(self, nb_diracs=1000): for _ in range(10): ot = OptimalTransport(self.domain) # diracs ot.set_positions(np.random.rand(nb_diracs, 2)) ot.set_weights(np.ones(nb_diracs)) # optimal weights ot.adjust_weights() # integrals areas = ot.pd.integrals() self.assertAlmostEqual(np.min(areas), 1.0 / nb_diracs, places=6) self.assertAlmostEqual(np.max(areas), 1.0 / nb_diracs, places=6)
def optimal_transport(density, Y, masses, psi0 = None, err=1e-8): center = (density.min_position() + density.max_position())/2 halfsides = (density.max_position() - density.min_position())/2 ratio = 1/np.max(np.abs((Y-center)/halfsides)) psi = (1-ratio)*np.sum((Y-center)**2, axis=-1) ot = OptimalTransport(Y, psi, density, radial_func=RadialFuncUnit(), obj_max_dw=err) ot.set_masses(masses) ot.adjust_weights() return ot.pd
from pysdot import OptimalTransport from matplotlib import pyplot import numpy as np positions = [] ss = 1e-3 for x in np.linspace(0, 1 - ss, 20): positions.append([x, 0.5]) positions.append([x + ss, 0.5]) ot = OptimalTransport(np.array(positions)) ot.verbosity = 1 ot.adjust_weights() pyplot.plot(ot.get_positions()[:, 0], ot.get_weights(), '+') pyplot.show()
# iterations weights = np.ones( positions.shape[ 0 ] ) * target_radius ** 2 timeout = np.zeros( positions.shape[ 0 ] ) color_values = positions[ :, 1 ] color_values = ( color_values - np.min( color_values ) ) / np.ptp( color_values ) h_weights = [] h_positions = [] T = 6.5 nb_timesteps = int( T / timestep ) display_timesteps = np.linspace(0, nb_timesteps-1, 100, dtype = int) ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights( weights ) ot.set_masses( np.ones( positions.shape[ 0 ] ) * np.pi * target_radius ** 2 ) for i in range( nb_timesteps ): print("iteration %d/%d for na=%d" % (i, nb_timesteps,na)) # optimal weights ot.set_positions( positions ) ot.adjust_weights() centroids = ot.get_centroids() # display if i in display_timesteps: print(i) j = display_timesteps.tolist().index(i)
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # initial positions, weights and masses positions = [] if n == 1: radius = 0.3 mass = 3.14159 * radius**2 positions.append([0.5, radius]) else: radius = l / (2 * (n - 1)) mass = l**2 / n**2 for y in np.linspace(radius, l - radius, n): for x in np.linspace(0.5 - l / 2 + radius, 0.5 + l / 2 - radius, n): nx = x + 0.0 * radius * (np.random.rand() - 0.5) ny = y + 0.0 * radius * (np.random.rand() - 0.5) + 0.5 * radius positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] # dim = positions.shape[ 1 ] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) ot.set_positions(positions) ot.max_iter = 100 ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk", points=True, centroids=True) # history of centroids ce = ot.get_centroids() ce[:, 1] += radius / 10 bh = [ce] dt = 1.0 for num_iter in range(200): print("num_iter", num_iter) bh.append(ot.get_centroids()) fit_positions(ot, bh, dt) # display n1 = int(num_iter / 1) + 1 ot.display_vtk(base_filename + "{}.vtk".format(n1), points=True, centroids=True)
]) num_dirac += 1 # plt.plot( res[ :, 0 ], res[ :, 1 ], "x" ) # plt.show() return res for dist_name in ["uniform"]: # , "voro_50" for dim in [3]: for nb_diracs in map( int, [1e5 / 8, 1e5 / 4, 1e5 / 2]): # 1e5, 2e5, 4e5, 8e5, 16e5 positions = make_positions(dist_name, nb_diracs, dim) # diracs ot = OptimalTransport(positions=positions) ot.verbosity = 1 # solve print(dim, nb_diracs) ot.adjust_weights() # display, save if nb_diracs <= 1e6: ot.display_vtk("vtk/pd.vtk", points=True) pw = np.zeros([dim + 1, nb_diracs]) for d in range(dim): pw[d, :] = positions[:, d] np.save( "/data/sdot/{}_{}_{}D_equalw.npy".format(
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() # domain.add_box([0, 0], [1, 1]) domain.add_convex_polyhedron([ # x y Nx Ny (ext) [0, 0, -1, -0.2], [0, 0, -0.2, -1], [1, 1, +1, 0], [1, 1, 0, +1], ]) # initial positions, weights and masses positions = [] if n == 1: radius = 0.2 else: radius = l / (2 * (n - 1)) for y in np.linspace(radius, l - radius, n): for x in np.linspace(radius, l - radius, n): nx = x + 0.2 * radius * (np.random.rand() - 0.5) ny = y + 0.2 * radius * (np.random.rand() - 0.5) positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * l**2 / nb_diracs) ot.set_positions(positions) ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk") ot.set_positions(ot.get_centroids()) velocity = 0.0 * positions for num_iter in range(200): print("num_iter", num_iter) # barycenters at the beginning ot.adjust_weights() b_o = ot.get_centroids() # trial for the new barycenters velocity[:, 0] -= 0.05 * radius * 0.707 velocity[:, 1] -= 0.05 * radius * 0.707 b_n = b_o + velocity # optimisation of positions to go to the target barycenters ropt = scipy.optimize.minimize(obj, b_n.flatten(), (ot, b_n), tol=1e-4, method='BFGS', options={'eps': 1e-4 * radius}) positions = ropt.x.reshape((-1, 2)) ot.set_positions(positions) ot.adjust_weights() # new barycenters, corrected (minimize have update the weights) b_n = ot.get_centroids() velocity = b_n - b_o print(positions, velocity) # display ot.pd.display_vtk_points(base_filename + "pts_{}.vtk".format(num_iter + 1)) ot.display_vtk(base_filename + "{}.vtk".format(num_iter + 1))
domain.add_box( [ 0, 0 ], [ 2, 1 ] ) domain.add_box( [ pos_door, 0.5 - opened_width / 2 ], [ limx, 0.5 + opened_width / 2 ] ) if obstacle_radius: domain.add_convex_polyhedron( np.array( pon ), -1.0 ) domain.display_boundaries_vtk( directory + "/bound.vtk" ) # domain_asy = "draw((0,0)--(3,0)--(3,1)--(4,1)--(4,0)--(7,0)--(7,3)--(4,3)--(4,2)--(3,2)--(3,3)--(0,3)--cycle);\n" s = 0.5 * target_radius g = GradGrid( domain, [ [ limx - 2 * s, 0.5 ] ], s ) # iterations color_values = positions[ :, 1 ] color_values = ( color_values - np.min( color_values ) ) / np.ptp( color_values ) ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights( np.ones( positions.shape[ 0 ] ) * target_radius ** 2 ) ot.set_masses( np.ones( positions.shape[ 0 ] ) * np.pi * target_radius ** 2 ) nb_timesteps = int( 20 / target_radius ) for i in range( nb_timesteps ): # change positions weights = ot.get_weights() for n in range( positions.shape[ 0 ] ): c = 1 / ( 10 * weights[ n ] / 7e-4 + 1 ) positions[ n, : ] += c * 0.5 * target_radius * g.grad( positions[ n, : ] ) # optimal weights ot.set_positions( positions ) ot.adjust_weights()
def quantization(ot, tau=.3, niter=10): for _ in range(niter): ot.adjust_weights() B = ot.get_centroids() ot.set_positions(ot.get_positions() + tau * (B - ot.get_positions())) ot.adjust_weights() # initial positions n = 40 positions = [] for y in range(n): for x in range(n): positions.append([(y + 0.25 + 0.5 * np.random.rand()) / n, (x + 0.25 + 0.5 * np.random.rand()) / n]) ot = OptimalTransport(np.array(positions)) ot.verbosity = 1 # solve for l in [2, 4, 8]: t = np.linspace(-1, 1, 100) x, y = np.meshgrid(t, t) img = np.exp(-l * (x**2 + y**2)) img /= np.mean(img) # domain ot.set_domain(ScaledImage([0, 0], [1, 1], img)) quantization(ot, 0.1, 10) # display # ot.pd.display_vtk( "results/pd.vtk", centroids=True )
from pysdot.domain_types import ConvexPolyhedraAssembly from pysdot.radial_funcs import RadialFuncInBall from pysdot import OptimalTransport import numpy as np domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 10]) R = 0.5 ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_masses(np.array([np.pi * R**2 / 2])) ot.set_weights(np.array([R**2])) cpt = 0 for y in np.linspace(0, -20, 100): ot.set_positions(np.array([[0.5, y]])) ot.adjust_weights() r = ot.get_weights()[0]**0.5 a = np.arcsin(R / r) e = 0.5 * r * (np.pi / 2 * np.sin(a) - a / np.sin(a) + np.cos(a)) f = 0.5 * (np.cos(a) + a / np.sin(a)) yp = y + r * f print(y, yp) ot.display_vtk("lc_{}.vtk".format(cpt)) cpt += 1
def run(n, base_filename): domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) domain.add_box([0.2, -0.5], [0.8, 0]) positions = [] radius = 0.5 / (2 * (n - 1)) for y in np.linspace(radius, 0.5 + radius, n): for x in np.linspace(radius, 0.5 + radius, n): positions.append([x, y]) nb_diracs = len(positions) # ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_masses(np.ones(nb_diracs) * 0.8 * 0.5**2 / nb_diracs) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_positions(np.array(positions)) b_old = ot.pd.centroids() ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk") nb_timesteps = int(20 / radius) v = np.zeros((nb_diracs, 2)) dt = 0.003 * radius for i in range(nb_timesteps): print(i, "/", nb_timesteps) # first trial v[:, 1] -= 1 p_old = ot.get_positions() p_tst = p_old + dt * v ot.set_positions(p_tst) ot.adjust_weights() # display d = int(n / 5) if i % d == 0: ot.display_vtk(base_filename + "{:03}.vtk".format(1 + int(i / d))) # corrections b_new = ot.pd.centroids() v = (b_new - b_old) / dt ot.set_positions(b_new) b_old = b_new
from pysdot.domain_types import ConvexPolyhedraAssembly from pysdot import OptimalTransport import numpy as np # # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # diracs ot = OptimalTransport(domain) ot.set_positions(np.random.rand(10, 2)) ot.set_weights(np.ones(ot.get_positions().shape[0])) # solve ot.adjust_weights() # display ot.display_vtk("results/pd.vtk") print(ot.pd.display_html())
domain.add_convex_polyhedron([[-1, -1, -1, 0], [-1, -1, 0, -1], [+2, -1, 1, -1], [-1, +2, 0, +1]]) domain.display_boundaries_vtk(directory + "/bounds.vtk") positions = [] for y in np.linspace(0, 1, n): for x in np.linspace(0, 1, n): if (x - .5)**2 + (y - .5)**2 <= .5**2: positions.append([x, y]) positions = np.array(positions) N = positions.shape[0] # iterations ot = OptimalTransport(domain, RadialFuncEntropy(eps)) ot2 = OptimalTransport(domain) ot.set_masses(np.ones(positions.shape[0]) / N) weights = np.zeros(positions.shape[0]) niter = int(T / tau) display_timesteps = np.linspace(0, niter - 1, 6, dtype=int) save_timesteps = np.linspace(0, niter - 1, 100, dtype=int) max_rho = -1 h_positions = [] for i in range(niter): #print("iteration %d/%d" % (i,niter)) # optimal weights ot.set_positions(positions) ot.adjust_weights()
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # initial positions, weights and masses positions = [] if n == 1: radius = 0.3 mass = 3.14159 * radius**2 positions.append([0.5, radius]) else: radius = l / (2 * (n - 1)) mass = l**2 / n**2 for y in np.linspace(radius, l - radius, n): for x in np.linspace(radius, l - radius, n): nx = x # + 0.2 * radius * (np.random.rand() - 0.5) ny = y # + 0.2 * radius * (np.random.rand() - 0.5) positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] dim = positions.shape[1] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) ot.set_positions(positions) ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk", points=True) g = np.zeros((nb_diracs, dim)) g[:, 1] = -0.001 bh = [ot.get_centroids()] # history of centroids for num_iter in range(50): bh.append(ot.get_centroids()) print("num_iter", num_iter) # proposition for centroids bn = 2 * bh[-1] - bh[-2] + g # find a new set of diracs parameters (position and weight) # to be as close to the new centroids as possible update_positions_to_get_centroids(ot, bn) # display n1 = num_iter + 1 ot.display_vtk(base_filename + "{}.vtk".format(n1), points=True)
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # initial positions, weights and masses positions = [] radius = l / (2 * (n - 1)) mass = l**2 / n**2 for y in np.linspace(radius, l - radius, n): for x in np.linspace(0.5 - l / 2 + radius, 0.5 + l / 2 - radius, n): nx = x + 0.0 * radius * (np.random.rand() - 0.5) ny = y + 0.0 * radius * (np.random.rand() - 0.5) positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] dim = positions.shape[1] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) ot.set_positions(positions) ot.max_iter = 100 ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk", points=True, centroids=True) # gravity G = np.zeros((nb_diracs, dim)) G[:, 1] = -9.81 # eps = 0.5 dt = radius * 0.1 V = np.zeros((nb_diracs, dim)) M = np.stack([ot.get_masses() for d in range(dim)]).transpose() for num_iter in range(500): print("num_iter:", num_iter, "dt:", dt) C = ot.get_centroids() X = ot.get_positions() A = G + (C - ot.get_positions()) / (M * eps**2) while True: dV = dt * A dX = dt * (V + dV) if np.max(np.linalg.norm(dX, axis=1, ord=2)) < 0.2 * radius: dt *= 1.05 V += dV X += dX break dt *= 0.5 ot.set_positions(X) ot.adjust_weights() # display n1 = int(num_iter / 1) + 1 ot.display_vtk(base_filename + "{}.vtk".format(n1), points=True, centroids=True)
class FluidSystem: def __init__( self, domain, positions, velocities, masses, base_filename ): self.ot = OptimalTransport(domain, RadialFuncInBall()) self.ot.set_positions(np.array(positions)) self.ot.set_weights(np.array(masses)/np.pi) self.ot.set_masses(np.array(masses)) self.base_filename = base_filename self.cpt_display = 0 self.max_iter = 200 self.time = 0 # initial centroid positions and velocities self.ot.adjust_weights() self.centroids = self.ot.get_centroids() self.velocities = np.array(velocities) self.coeff_centroid_force = 1e-4 def display( self ): fn = "{}{}.vtk".format( self.base_filename, self.cpt_display ) self.ot.display_vtk( fn, points=True, centroids=True ) self.cpt_display += 1 def make_step( self ): ratio_dt = 1.0 while self.try_step( ratio_dt ) == False: ratio_dt *= 0.5 print( " dt ratio:", ratio_dt ) def try_step( self, ratio_dt ): old_p = self.ot.get_positions() # find dt radii_ap = ( np.array( self.ot.get_masses() ) / np.pi ) ** 0.5 vn2 = np.linalg.norm( self.velocities, axis=1, ord=2 ) dt = ratio_dt * 0.2 / np.max( np.abs( vn2 / radii_ap ) ) adv = dt * self.velocities # target centroid positions + initial guess for the dirac positions target_centroids = self.centroids + adv self.ot.set_positions( old_p + adv ) # stuff to extract centroids, masses, ... d = self.ot.dim() n = self.ot.nb_diracs() rd = np.arange( d * n, dtype=np.int ) b0 = ( d + 1 ) * np.floor_divide( rd, d ) l0 = b0 + rd % d # l1 = (d + 1) * np.arange(n, dtype=np.int) + d # find positions to fit the target centroid positions ratio = 1.0 for num_iter in range( self.max_iter + 1 ): if num_iter == self.max_iter: self.ot.set_positions( old_p ) return False # search dir mvs = self.ot.pd.der_centroids_and_integrals_wrt_weight_and_positions() if mvs.error: self.ot.set_positions( old_p ) ratio *= 0.5 if ratio < 1e-2: return False print( " solve X ratio:", ratio ) continue M = csr_matrix( ( mvs.m_values, mvs.m_columns, mvs.m_offsets ) )[ l0, : ][ :, l0 ] V = mvs.v_values[ l0 ] - target_centroids.flatten() c = self.coeff_centroid_force * np.max( M ) V += c * ( self.ot.get_positions() - target_centroids ).flatten() M += c * diag( 2 * n ) X = spsolve( M, V ).reshape( ( -1, d ) ) # if np.linalg.norm( X, ord=np.inf ) > self.max_disp_at_each_sub_iter: # X *= self.max_disp_at_each_sub_iter / np.linalg.norm( X, ord=np.inf ) self.ot.set_positions( self.ot.get_positions() - ratio * X ) e = np.linalg.norm( X ) # print( " e", e ) if e < 1e-6: break # projection # self.ot.verbosity = 1 self.ot.adjust_weights( relax=0.75 ) # update centroid pos and speed self.time += dt old_centroids = self.centroids self.centroids = self.ot.get_centroids() self.velocities = ( self.centroids - old_centroids ) / dt return True
def make_case(name, nb_diracs, dim): # default domain if name == "random": positions = np.random.rand(nb_diracs, dim) elif name == "grid": positions = make_grid(nb_diracs, dim) elif name == "grid_with_rand": positions = make_grid(nb_diracs, dim, rand_val=1) elif name == "faces": # voronoi with 100 points pd = PowerDiagram(np.random.rand(5, dim)) # quantization lot = OptimalTransport(positions=make_grid(nb_diracs, dim)) lot.obj_max_dw = 1e-5 lot.verbosity = 1 for ratio in [1 - 0.85**n for n in range(50)]: # density img_size = 1000 img_points = [] items = [range(img_size) for i in range(dim)] for i in itertools.product(*items): img_points.append(i) img = pd.distances_from_boundaries( np.array(img_points) / img_size).reshape((img_size, img_size)) img = (1 - ratio) + ratio * np.exp(-(100 * img)**2) lot.set_domain(ScaledImage([0, 0], [1, 1], img / np.mean(img))) # opt for _ in range(10): lot.adjust_weights() B = lot.get_centroids() lot.set_positions(lot.get_positions() + 0.3 * (B - lot.get_positions())) positions = lot.get_positions() plt.plot(positions[:, 0], positions[:, 1], ".") plt.show() np.save("/data/{}_n{}_d{}_voro.npy".format(name, nb_diracs, dim), (positions[:, 0], positions[:, 1])) # solve if nb_diracs < 32000000: ot = OptimalTransport(positions) # ot.verbosity = 1 # solve ot.adjust_weights() # display # ot.display_vtk( "results/pd.vtk" ) np.save("/data/{}_n{}_d{}.npy".format(name, nb_diracs, dim), (positions[:, 0], positions[:, 1], ot.get_weights()))
[+2, -1, 1, -1], [-1, +2, 0, +1]]) domain.display_boundaries_vtk(directory + "/bounds.vtk") # positions = [] for y in np.linspace(0, 1, n): for x in np.linspace(0, 1, n): positions.append([x, y]) positions = np.array(positions) # iterations max_w = -1 min_w = 0 ot = OptimalTransport(domain, RadialFuncEntropy(eps)) ot.set_masses(np.ones(positions.shape[0])) weights = np.zeros(positions.shape[0]) for i in range(101): # optimal weights ot.set_positions(positions) ot.adjust_weights() weights = ot.get_weights() min_w = np.min(weights) max_w = np.max(weights) # display if i % 10 == 0: ot.display_asy(directory + "/we_{:03}.asy".format(int(i / 10)),
from pysdot.domain_types import ConvexPolyhedraAssembly from pysdot import OptimalTransport import numpy as np positions = np.random.rand(200, 2) # diracs ot = OptimalTransport() ot.set_positions(np.array(positions)) ot.set_weights(np.ones(ot.get_positions().shape[0])) ot.verbosity = 1 # solve ot.adjust_weights() # display ot.display_vtk("results/pd.vtk") # print( ot.pd.display_html() )
dws = 5 img = imageio.imread("clay.jpg") img = img[:, :, 1] beg = int(img.shape[1] / 2 - img.shape[0] / 2) end = beg + img.shape[0] img = img[:, beg:end] img = downscale_local_mean(img, (dws, dws)) img = np.max(img) * 1.05 - img img /= np.sum(img) # plt.imshow( img ) # plt.show() # domain domain = ConvexPolyhedraAssembly() domain.add_img([0, 0], [1, 1], img) # diracs nd = 100000 ot = OptimalTransport(domain) ot.set_positions(np.random.rand(nd, 2)) ot.set_weights(np.ones(nd) / nd) ot.obj_max_dw = 1e-5 ot.verbosity = True # solve ot.adjust_weights(relax=1.0) # display ot.pd.display_vtk("results/pd.vtk", centroids=True)
ot.set_weights(np.array(masses) / np.pi * 0.25) ot.set_masses(np.array(masses)) ot.max_iter = 100 ot.adjust_weights(relax=0.5) ot.display_vtk("lc_{}.vtk".format(cpt)) return ot.pd.der_boundary_integral() domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [10, 10]) crb = {} for n in range(30, 31): ot = OptimalTransport(domain, RadialFuncInBall()) k = "{}".format(n) crb[k] = [] cpt = 0 for coeff_r in [0.9875]: # np.linspace( 0.9875, 0.4, 120 ): e = test_discr(ot, n, coeff_r, cpt) print(e) # crb[ k ].append( [ coeff_r, e ] ) # cpt += 1 # for key, val in crb.items(): # val = np.array( val ) # plt.plot( val[ :, 0 ], val[ :, 1 ] ) # plt.show()
# helper function def quantization(ot, tau=.3, niter=10): for _ in range(niter): ot.adjust_weights() B = ot.get_centroids() ot.set_positions(ot.get_positions() + tau * (B - ot.get_positions())) ot.adjust_weights() # initial positions n = 30 positions = [] for y in range(n): for x in range(n): positions.append([np.random.rand(), np.random.rand()]) ot = OptimalTransport(np.array(positions)) ot.verbosity = 1 # solve for l in [0.5, 1, 2, 4]: # , 8, 16 print(l) tx = np.linspace(-1, 1, 500) ty = np.linspace(-1, 1, 500) x, y = np.meshgrid(tx, ty) img = np.exp(-l * (x**2 + y**2)) img /= np.mean(img) # domain #ot.set_domain(ScaledImage([0, 0], [1, 1], img)) #quantization(ot, 0.1, 10)