Exemplo n.º 1
0
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()))
 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()
Exemplo n.º 3
0
    def setUp(self):
        rf = RadialFuncArfd(
            lambda r: ((1 - r * r) * (r < 1))**2.5,  # value
            lambda w: 1 / w**0.5,  # input scaling
            lambda w: w**2.5,  # output scaling
            lambda r: 2.5 * ((1 - r * r) *
                             (r < 1))**1.5,  # value for the der wrt weight
            lambda w: 1 / w**0.5,  # input scaling for the der wrt weight
            lambda w: w**1.5,  # output scaling for the der wrt weight
            [1],  # stops (radii values where we may have discontinuities)
            1e-8  # precision
        )

        # set up a domain, with only 1 dirac
        domain = ConvexPolyhedraAssembly()
        domain.add_box([0.0, 0.0], [2.0, 1.0])

        self.pd = PowerDiagram(domain=domain, radial_func=rf)
Exemplo n.º 4
0
    def test_unit(self):
        pd = PowerDiagram(domain=self.domain)
        pd.set_positions([[0.0, 0.0]])
        pd.set_weights([0.0])

        areas = pd.integrals()
        self.assertAlmostEqual(areas[0], 1.0)

        centroids = pd.centroids()
        self.assertAlmostEqual(centroids[0][0], 0.5)
        self.assertAlmostEqual(centroids[0][1], 0.5)
Exemplo n.º 5
0
    def setUp(self):
        rf = RadialFuncArfd(
            lambda r: (1 - r * r) * (r < 1),  # value
            lambda w: 1 / w**0.5,  # input (radius) scaling
            lambda w: w,  # output scaling
            lambda r: r < 1,  # value for the der wrt weight
            lambda w: 1 / w**0.5,  # input scaling for the der wrt weight
            lambda w: 1,  # output scaling for the der wrt weight
            [1]  # stops (radii value where we may have discontinuities)
        )

        # should use only 2 polynomials
        self.assertEqual(rf.nb_polynomials(), 2)

        # set up a domain, with only 1 dirac
        domain = ConvexPolyhedraAssembly()
        domain.add_box([0.0, 0.0], [2.0, 1.0])

        self.pd = PowerDiagram(domain=domain, radial_func=rf)
Exemplo n.º 6
0
        def tg(position, w, eps, ei, ec):
            pd = PowerDiagram(radial_func=RadialFuncEntropy(eps),
                              domain=self.domain)
            pd.set_positions([position])
            pd.set_weights([w])

            res = pd.integrals()
            self.assertAlmostEqual(res[0], ei, 5)

            res = pd.centroids()
            self.assertAlmostEqual(res[0][0], ec[0], 5)
            self.assertAlmostEqual(res[0][1], ec[1], 5)
def laguerre_areas(domain, Y, psi, der=False):
    """
    Computes the areas of the Laguerre cells intersected with the domain.
    Args:
        domain (pysdot.domain_types): domain of the (continuous)
                                      source measure
        Y (np.array): points of the (discrete) target measure
        psi (np.array or list): Kantorovich potentials
        der (bool): wether or not return the Jacobian of the areas
                    w.r.t. psi
    Returns:
        pd.integrals() (list): list of areas of Laguerre cells
    """
    pd = PowerDiagram(Y, -psi, domain)
    if der:
        N = len(psi)
        mvs = pd.der_integrals_wrt_weights()
        return mvs.v_values, csr_matrix(
            (-mvs.m_values, mvs.m_columns, mvs.m_offsets), shape=(N, N))
    else:
        return pd.integrals()
Exemplo n.º 8
0
    def test_sum_area(self, nb_diracs=100):
        for _ in range(10):
            # diracs
            pd = PowerDiagram(domain=self.domain)
            pd.set_positions(np.random.rand(nb_diracs, 3))
            pd.set_weights(np.ones(nb_diracs))

            # integrals
            areas = pd.integrals()
            self.assertAlmostEqual(np.sum(areas), 1.0)
Exemplo n.º 9
0
    def _test_der(self, positions, weights, rf):
        pd = PowerDiagram(self.domain, rf)
        pd.set_positions(np.array(positions, dtype=np.double))
        pd.set_weights(np.array(weights, dtype=np.double))

        pd.display_vtk("der_int.vtk")

        num = pd.der_integrals_wrt_weight_and_positions()
        print("------------", num.error)
        if num.error:
            return

        ndi = len(positions)
        mat = np.zeros((ndi, ndi))
        for i in range(ndi):
            for o in range(num.m_offsets[i + 0], num.m_offsets[i + 1]):
                mat[i, num.m_columns[o]] = num.m_values[o]

        print("------------", mat)
Exemplo n.º 10
0
    def test_integrals(self):
        # diracs
        rd = 2.0
        pd = PowerDiagram(domain=self.domain, radial_func=RadialFuncPpWmR2())
        pd.set_positions(np.array([[1.0, 0.0], [5.0, 5.0]]))
        pd.set_weights(np.array([rd**2, rd**2]))

        # integrals
        ig = pd.integrals()

        # Integrate[ Integrate[ ( 4 - ( x * x + y * y ) ) * UnitStep[ 2^2 - x^2 - y^2 ] , { x, -1, 2 } ], { y, 0, 3 } ]
        self.assertAlmostEqual(ig[0], 10.97565662)
        self.assertAlmostEqual(ig[1], 8 * np.pi)

        # centroids
        ct = pd.centroids()

        # Integrate[ Integrate[ x * ( 4 - ( x * x + y * y ) ) * UnitStep[ 2^2 - x^2 - y^2 ] , { x, -1, 2 } ], { y, 0, 3 } ]
        self.assertAlmostEqual(ct[0][0], 1.18937008)
        self.assertAlmostEqual(ct[0][1], 0.69699702)

        self.assertAlmostEqual(ct[1][0], 5)
        self.assertAlmostEqual(ct[1][1], 5)
Exemplo n.º 11
0
from pysdot.domain_types import ConvexPolyhedraAssembly
from pysdot import PowerDiagram
import numpy as np

positions = np.random.rand( 30, 2 )

domain = ConvexPolyhedraAssembly()
domain.add_box([-1, -1], [2, 2])

# diracs
pd = PowerDiagram( positions, domain = domain )
pd.add_replication( [ +1, 0 ] )
pd.add_replication( [ -1, 0 ] )
pd.display_vtk( "pb.vtk" )
Exemplo n.º 12
0
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 )
Exemplo n.º 13
0
from pysdot.domain_types import ConvexPolyhedraAssembly
from pysdot import PowerDiagram
import matplotlib.pyplot as plt
import numpy as np

positions = np.array( [
    [ 0.0, 0.5 ],
    [ 1.0, 0.5 ],
] )

domain = ConvexPolyhedraAssembly()
domain.add_box([0, 0], [1, 1])

# diracs
pd = PowerDiagram( positions, domain = domain )
l = []
for i in range( 10000 ):
    l.append( pd.centroids( 0.5 ) )
l = np.vstack( l )

plt.plot( l[ :, 0 ], l[ :, 1 ], '.' )
plt.show()
Exemplo n.º 14
0
    def _test_der(self, positions, weights, rf):
        pd = PowerDiagram(self.domain, rf)
        pd.set_positions(np.array(positions, dtype=np.double))
        pd.set_weights(np.array(weights, dtype=np.double))

        num = pd.der_integrals_wrt_weights()
        if num.error:
            return

        ndi = len(positions)
        mat = np.zeros((ndi, ndi))
        for i in range(ndi):
            for o in range(num.m_offsets[i + 0], num.m_offsets[i + 1]):
                mat[i, num.m_columns[o]] = num.m_values[o]

        eps = 1e-6
        res = pd.integrals()
        delta = np.max(np.abs(mat)) * 200 * eps
        for i in range(ndi):
            pd.set_weights(
                np.array([weights[j] + eps * (i == j) for j in range(ndi)]))
            des = pd.integrals()
            der = (des - res) / eps
            for j in range(ndi):
                self.assertAlmostEqual(mat[i, j], der[j], delta=delta)
Exemplo n.º 15
0
class TestArfd_2D_1p5(unittest.TestCase):
    def setUp(self):
        rf = RadialFuncArfd(
            lambda r: ((1 - r * r) * (r < 1))**2.5,  # value
            lambda w: 1 / w**0.5,  # input scaling
            lambda w: w**2.5,  # output scaling
            lambda r: 2.5 * ((1 - r * r) *
                             (r < 1))**1.5,  # value for the der wrt weight
            lambda w: 1 / w**0.5,  # input scaling for the der wrt weight
            lambda w: w**1.5,  # output scaling for the der wrt weight
            [1],  # stops (radii values where we may have discontinuities)
            1e-8  # precision
        )

        # set up a domain, with only 1 dirac
        domain = ConvexPolyhedraAssembly()
        domain.add_box([0.0, 0.0], [2.0, 1.0])

        self.pd = PowerDiagram(domain=domain, radial_func=rf)

    def test_integrals(self):
        self.pd.set_positions(np.array([[0.0, 0.0]]))

        # weights and expected values (w = weight, i = integral, c = centroid)
        l = [
            {
                "w": 10.0,
                "i": 417.0399,
                "c": [0.815858, 0.476057]
            },
            {
                "w": 20.0,
                "i": 2902.3809,
                "c": [0.911708, 0.488773]
            },
            {
                "w": 100.0,
                "i": 191826.6661,
                "c": [0.983124, 0.497884]
            },
        ]

        # NumberForm[ N[ Integrate[ Integrate[ (  10 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ] => 417.0399438275571
        # NumberForm[ N[ Integrate[ Integrate[ (  20 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ] => 2902.3809
        # NumberForm[ N[ Integrate[ Integrate[ ( 100 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ] => 191826.6661

        # NumberForm[ N[ Integrate[ Integrate[ x * (  10 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ] / Integrate[ Integrate[ (  10 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ]
        # NumberForm[ N[ Integrate[ Integrate[ y * (  10 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ] / Integrate[ Integrate[ (  10 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ]

        # NumberForm[ N[ Integrate[ Integrate[ x * (  20 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ] / Integrate[ Integrate[ (  20 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ]
        # NumberForm[ N[ Integrate[ Integrate[ y * (  20 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ] / Integrate[ Integrate[ (  20 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ]

        # NumberForm[ N[ Integrate[ Integrate[ x * ( 100 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ] / Integrate[ Integrate[ ( 100 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ]
        # NumberForm[ N[ Integrate[ Integrate[ y * ( 100 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ] / Integrate[ Integrate[ ( 100 - ( x * x + y * y ) ) ^ 2.5, { x, 0, 2 } ], { y, 0, 1 } ], 10 ], 10 ]

        # test integrals and centroids
        for d in l:
            self.pd.set_weights(np.array([d["w"]]))

            ig = self.pd.integrals()
            self.assertAlmostEqual(ig[0], d["i"], places=2)

            cs = self.pd.centroids()
            for (v, e) in zip(cs[0], d["c"]):
                self.assertAlmostEqual(v, e, delta=1e-3)

    def test_derivatives(self):
        self.pd.set_positions(np.array([[0.0, 0.0], [1.0, 0.0]]))
        self.pd.set_weights(np.array([1.0, 2.0]))
        check_ders(self, self.pd)
Exemplo n.º 16
0
    def test_derivatives(self):
        # diracs
        rd = 2.0
        weights = np.array([rd**2, rd**2])
        pd = PowerDiagram(domain=self.domain, radial_func=RadialFuncPpWmR2())
        pd.set_positions(np.array([[1.0, 0.0], [5.0, 5.0]]))
        pd.set_weights(weights.copy())

        # derivatives
        num = pd.der_integrals_wrt_weights()

        ndi = pd.weights.shape[0]
        mat = np.zeros((ndi, ndi))
        for i in range(ndi):
            for o in range(num.m_offsets[i + 0], num.m_offsets[i + 1]):
                mat[i, num.m_columns[o]] = num.m_values[o]

        # numerical
        eps = 1e-6
        res = pd.integrals()
        delta = np.max(np.abs(mat)) * 100 * eps
        for i in range(ndi):
            pd.set_weights(
                np.array([weights[j] + eps * (i == j) for j in range(ndi)]))
            des = pd.integrals()
            der = (des - res) / eps
            for j in range(ndi):
                #self.assertAlmostEqual(mat[i, j], der[j], delta=delta)
                print(mat[i, j], der[j])
Exemplo n.º 17
0
from pysdot.domain_types import ConvexPolyhedraAssembly
from pysdot import PowerDiagram
import numpy as np

positions = np.array([[0.25, 0.5], [0.75, 0.5]])

# domain = ConvexPolyhedraAssembly()
# domain.add_box( [ 0, 0 ], [ 0.5, 1 ], 1 )
# domain.add_box( [ 0.5, 0 ], [ 1, 1 ], 0.1 )

# diracs
pd = PowerDiagram(positions)
print(np.sum(pd.second_order_moments()))

positions[0, 0] = 0.0

pd = PowerDiagram(positions)
print(np.sum(pd.second_order_moments()))
Exemplo n.º 18
0
from pysdot import PowerDiagram
import pylab as plt
import numpy as np

positions = np.random.rand(10, 2)

# diracs
pd = PowerDiagram(positions)

points = []
for y in np.linspace(0, 1, 100):
    for x in np.linspace(0, 1, 100):
        points.append([x, y])

dist = pd.distances_from_boundaries(np.array(points))
dist = dist.reshape((100, 100))
print(dist.shape)

plt.imshow(dist)
plt.colorbar()
plt.show()
Exemplo n.º 19
0
class TestArfd_2D(unittest.TestCase):
    def setUp(self):
        rf = RadialFuncArfd(
            lambda r: (1 - r * r) * (r < 1),  # value
            lambda w: 1 / w**0.5,  # input (radius) scaling
            lambda w: w,  # output scaling
            lambda r: r < 1,  # value for the der wrt weight
            lambda w: 1 / w**0.5,  # input scaling for the der wrt weight
            lambda w: 1,  # output scaling for the der wrt weight
            [1]  # stops (radii value where we may have discontinuities)
        )

        # should use only 2 polynomials
        self.assertEqual(rf.nb_polynomials(), 2)

        # set up a domain, with only 1 dirac
        domain = ConvexPolyhedraAssembly()
        domain.add_box([0.0, 0.0], [2.0, 1.0])

        self.pd = PowerDiagram(domain=domain, radial_func=rf)

    def test_integrals(self):
        self.pd.set_positions(np.array([[0.0, 0.0]]))

        # weights and expected values (w = weight, i = integral, c = centroid)
        l = [
            {
                "w": 0.5,
                "i": np.pi / 32,
                "c": [8 * 2**0.5 / (15 * np.pi)] * 2
            },
            {
                "w": 1,
                "i": np.pi / 8,
                "c": [16.0 / (15 * np.pi)] * 2
            },
            {
                "w": 10,
                "i": 50 / 3,
                "c": [23.0 / 25, 49.0 / 100]
            },
            {
                "w": 100,
                "i": 590 / 3,
                "c": [293.0 / 295, 589.0 / 1180]
            },
        ]

        # test integrals and centroids
        for d in l:
            self.pd.set_weights(np.array([d["w"]]))

            ig = self.pd.integrals()
            self.assertAlmostEqual(ig[0], d["i"], places=5)

            cs = self.pd.centroids()
            for (v, e) in zip(cs[0], d["c"]):
                self.assertAlmostEqual(v, e, places=5)

    def test_derivatives(self):
        self.pd.set_positions(np.array([[0.0, 0.0], [1.0, 0.0]]))
        self.pd.set_weights(np.array([1.0, 2.0]))
        check_ders(self, self.pd)