.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "usage/usage.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_usage_usage.py: ===== Usage ===== .. GENERATED FROM PYTHON SOURCE LINES 8-9 The usage example assumes the package is imported as: .. GENERATED FROM PYTHON SOURCE LINES 9-12 .. code-block:: default import local2global as l2g .. GENERATED FROM PYTHON SOURCE LINES 13-14 For consistent results, fix the seed for the random number generator: .. GENERATED FROM PYTHON SOURCE LINES 14-17 .. code-block:: default l2g.utils.seed(42) .. GENERATED FROM PYTHON SOURCE LINES 18-30 Generate synthetic test data and patches ---------------------------------------- The goal for the local2global algorithm is to transform a set of separate patch embeddings into a global node embedding. The assumptions are that the patch embeddings perturbed parts of a global node embedding where the perturbations consist of scaling, rotation, reflection, translation and random noise. To work, the patches need to overlap such that the patch graph forms a single connected component where we consider a pair of patches to be connected if they share at least ``dim + 1`` nodes (``dim`` is the embedding dimension). For illustration and testing purposes, the package contains code to generate artificial test data (see :py:mod:`local2global.example`). This is not imported by default and to make it available use: .. GENERATED FROM PYTHON SOURCE LINES 30-33 .. code-block:: default import local2global.example as ex .. GENERATED FROM PYTHON SOURCE LINES 34-35 Also import matplotlib to visualise the results: .. GENERATED FROM PYTHON SOURCE LINES 35-38 .. code-block:: default import matplotlib.pyplot as plt .. GENERATED FROM PYTHON SOURCE LINES 39-42 First generate a ground-truth embedding using :py:func:`~local2global.example.generate_data`. In this example, we generate data with 5 clusters, where each cluster has a maximum size of 300 points, points within each cluster are normally distributed with a standard deviation of 0.2, and cluster centers are uniformly spaced on the unit circle. .. GENERATED FROM PYTHON SOURCE LINES 42-45 .. code-block:: default points = ex.generate_data(n_clusters=5, max_size=300, std=0.2) .. GENERATED FROM PYTHON SOURCE LINES 46-47 Visualise the data: .. GENERATED FROM PYTHON SOURCE LINES 47-51 .. code-block:: default plt.scatter(points[:, 0], points[:, 1], s=1, c='k') plt.show() .. image:: /usage/images/sphx_glr_usage_001.png :alt: usage :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 52-53 Next, we split the test data into 10 overlapping patches using :py:func:`~local2global.example.Voronoi_patches`. .. GENERATED FROM PYTHON SOURCE LINES 53-56 .. code-block:: default patches = ex.Voronoi_patches(points=points, sample_size=10, eps=1.5, kmeans=True) .. GENERATED FROM PYTHON SOURCE LINES 57-74 In this case we first identify the patch centers using k-means clustering and assign points to the patch with the nearest center and any other patch whose center is within 1.5 times the distance to the nearest center. Patches may be expanded further to satisfy some connectivity constraints on the patch graph (see :py:func:`~local2global.example.Voronoi_patches`) Local2global algorithm ---------------------- Set up alignment problem ++++++++++++++++++++++++ The main interface to the local2global algorithm is provided by :py:class:`~local2global.utils.AlignmentProblem` which weights each patch edge equally and :py:class:`~local2global.utils.WeightedAlignmentProblem` which weights patch edges by the size of the patch overlap and can be more robust when patch overlaps are heterogeneous. Both classes implement the same interface and expect a list of :py:class:`~local2global.utils.Patch` objects (such as generated by :py:func:`~local2global.example.Voronoi_patches`) as the main input and accept some other options to control the behaviour. Here we use the default options: .. GENERATED FROM PYTHON SOURCE LINES 74-77 .. code-block:: default problem = l2g.AlignmentProblem(patches) .. GENERATED FROM PYTHON SOURCE LINES 78-82 Perturb the patch embeddings ++++++++++++++++++++++++++++ For testing we add some random rotations/reflections, shifts and normally distributed noise to the patch embeddings: .. GENERATED FROM PYTHON SOURCE LINES 82-87 .. code-block:: default true_rotations = ex.rand_rotate_patches(problem) true_shifts = ex.rand_shift_patches(problem, shift_scale=1) ex.add_noise(problem, 0.01) .. GENERATED FROM PYTHON SOURCE LINES 88-89 Visualise the results: .. GENERATED FROM PYTHON SOURCE LINES 89-94 .. code-block:: default for p in problem.patches: plt.scatter(p.coordinates[:, 0], p.coordinates[:, 1], alpha=.5) plt.show() .. image:: /usage/images/sphx_glr_usage_002.png :alt: usage :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 95-96 For comparison we also set up a weighted problem with the same noise: .. GENERATED FROM PYTHON SOURCE LINES 96-99 .. code-block:: default weighted_problem = l2g.WeightedAlignmentProblem(problem.patches) .. GENERATED FROM PYTHON SOURCE LINES 100-104 Recover global embedding ++++++++++++++++++++++++ Use .. GENERATED FROM PYTHON SOURCE LINES 105-109 .. code-block:: default recovered_points = problem.get_aligned_embedding() recovered_points_weighted = weighted_problem.get_aligned_embedding() .. GENERATED FROM PYTHON SOURCE LINES 110-113 to run the local2global algorithm and reconstruct the global embedding. The results are cached and subsequent calls to :py:meth:`~local2global.utils.AlignmentProblem.get_aligned_embedding` return the cached result without rerunning the algorithm unless run with ``realign=True``. We can visualise the reconstruction error using .. GENERATED FROM PYTHON SOURCE LINES 113-118 .. code-block:: default error = ex.plot_reconstruction(points, problem) plt.title(f"unweighted (Procrustes error: {error:.3g})") plt.show() .. image:: /usage/images/sphx_glr_usage_003.png :alt: unweighted (Procrustes error: 0.00021) :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 119-120 and .. GENERATED FROM PYTHON SOURCE LINES 120-125 .. code-block:: default error_weighted = ex.plot_reconstruction(points, weighted_problem) plt.title(f"weighted (Procrustes error: {error_weighted:.3g})") plt.show() .. image:: /usage/images/sphx_glr_usage_004.png :alt: weighted (Procrustes error: 0.000201) :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 22.092 seconds) .. _sphx_glr_download_usage_usage.py: .. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: usage.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: usage.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_