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 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)
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 __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 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
def dist_noncongested(points, domain, center=None, epsilon=1, 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 = proj_noncongested(points=points, domain=domain, center=center, mass=mass, radial_func=radial_func, verbose=verbose) transport_cost = 0.5 / epsilon * np.sum(laguerre.second_order_moments()) barycenters = laguerre.centroids() gradient = mass.reshape(nb_points, 1) / epsilon * (points - barycenters) return transport_cost, gradient
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)
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()
radius=x-point_infinity_1 result=np.zeros(3) result[0]=np.sum(radius**2) result[1:]= radius*2 return result nb_double = 6 time = 15 nb_players_x=20 nb_players_y=20 nb_players=nb_players_x*nb_players_y dimension=2 mass=10*np.ones(nb_players)/nb_players epsilon=0.01 radial_func=RadialFuncInBall() center=None X,Y = np.meshgrid(np.linspace(0,4,nb_players_x), np.linspace(0,4,nb_players_y)) positions_init = np.zeros((nb_players,2)) positions_init[:,0] = X.flatten() positions_init[:,1] = Y.flatten() situation_init=Situation_Init(positions=positions_init, mass=mass) initial_guess=Trajectories(situation_init=situation_init) energy=Energy(domain=domain, radial_func=RadialFuncInBall(), epsilon=epsilon, time=time, lagrangian=lambda x:3*np.array([np.sum(x**2)/2,x[0],x[1]]), potential_t=potential_circ, potential_fin=potential_infinity) optimal_trajectories=energy.minimize(initial_guess=initial_guess, center=center, nb_steps=2**nb_double, steps_global= 2**nb_double, mode='double_middle', nb_procs=30, error=1e-8)
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))
return np.zeros(3) def potential_fin(x): return np.array([Spline.ev(x[0],x[1]), Spline.ev(x[0],x[1],dx=1),Spline.ev(x[0],x[1],dy=1)]) nb_double = 8 time = 600 nb_players_x=20 nb_players_y=20 nb_players=nb_players_y*nb_players_x dimension=2 mass=50*np.ones(nb_players)/nb_players epsilon=.1 radial_func=RadialFuncInBall() center=None X,Y = np.meshgrid(np.linspace(0.3,7.7,nb_players_x), np.linspace(0.3,7.7,nb_players_y)) positions_init = np.zeros((nb_players,2)) positions_init[:,0] = X.flatten() positions_init[:,1] = Y.flatten() situation_init=Situation_Init(positions=positions_init, mass=mass) initial_guess=Trajectories(situation_init=situation_init) energy=Energy(domain=domain, radial_func=radial_func, epsilon=epsilon, time=time, lagrangian=lambda x:4*np.array([np.sum(x**2)/2,x[0],x[1]]), potential_t=potential_t, potential_fin=potential_fin) optimal_trajectories=energy.minimize(initial_guess=initial_guess, center=center, nb_steps=2**nb_double, steps_global= 2**nb_double, mode='double_middle', nb_procs=30, error=1e-8, solver="sopt.minimize")
from pysdot.domain_types import ConvexPolyhedraAssembly from pysdot.radial_funcs import RadialFuncInBall from pysdot import OptimalTransport from pysdot import PowerDiagram import pylab as plt import numpy as np import unittest domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) positions = [ [ 0.25, 0.5 ], [ 0.75, 0.5 ] ] weights = [ 0.25**2, 0.25**2 ] pd = PowerDiagram( positions, weights, domain, radial_func=RadialFuncInBall()) img = pd.image_integrals( [ 0, 0 ], [ 1, 1 ], [ 100, 100 ] ) img[ :, :, 0 ] *= 1e4 img[ :, :, 1 ] *= 1e4 # for d in range( 3 ): # plt.subplot( 1, 3, d + 1 ) # plt.imshow( img[ :, :, d ] ) # plt.colorbar() # plt.show() # w = 0.1 # print( np.pi * w )
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)