def fit_transport_plans(self, point_clouds, masses=None, rescaling=True,
                         maxerr=1e-6, maxiter=20, t_init=1.,
                         *args, **kwargs):
     """
     Fits transport plans to point clouds.
     Args:
         point_clouds (dict): dictionary of point clouds
         masses (dict): dictionary of masses assigned to each point cloud
                        (default will be uniform masses for each point cloud)
         rescaling (bool): rescale or not the coordinates of point clouds
                           to fit in [0, 1]² to make computations easier 
                           (rescaling undone when returning transport plans)
         maxerr (float): threshold error under which Newton's algo stops
         maxiter (int): threshold iteration under which Newton's algo stops
         t_init (float): inital value of t for Newton's algorithm 
     """
     nb_clouds = len(point_clouds)
     cloud_keys = list(point_clouds.keys())
     # compute the transport plan of each cloud
     self.potentials = {}
     self.transport_plans = np.zeros((nb_clouds, 2 * self.grid_size**2))
     for c in range(nb_clouds):
         # get point cloud
         sample = point_clouds[cloud_keys[c]].astype('float64')
         N = len(sample)
         if rescaling:
             # rescale to [0, 1]²
             sample_min, sample_max = np.min(sample, axis=0), np.max(sample, axis=0)
             sample = (sample - sample_min) / (sample_max - sample_min) 
         # build target measure
         if masses is not None:
             nu = masses[cloud_keys[c]]
         else:
             nu = np.ones(N)/N
         # compute OT between source and target (get Kantorovich potentials)
         self.potentials[c] = newton_ot(self.domain, sample, nu, psi0=None, verbose=False,
                                        maxerr=maxerr, maxiter=maxiter, t_init=t_init)
         # build the *discretized* transport plan associated to these potentials
         pd = PowerDiagram(sample, -self.potentials[c], self.domain)
         img = pd.image_integrals([0, 0], [1, 1], [self.grid_size, self.grid_size])
         img /= np.expand_dims(img[ :, :, 2], -1)
         if rescaling:
             # undo rescaling
             img[:, :, :2] = (sample_max - sample_min) * img[:, :, :2] + sample_min 
         # save transport plan            
         self.transport_plans[c] = img[:, :, :2].flatten()
Exemple #2
0
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 )
# print( np.pi / 2 * w**2 )