├── .binder └── requirements.txt ├── .github └── workflows │ └── test_notebooks.yml ├── .gitignore ├── DTM_filtrations.py ├── Images ├── CodeCogsEqnRp.gif ├── MatchingDiag.png ├── Pers14.PNG ├── Simplex_tree_representation.png ├── nappe_distance_avec_bruit.png ├── nappe_distance_sans_bruit.png ├── nappe_dtm_avec_bruit.png ├── pers.png ├── persistence.png ├── sous_niveau_kPDTM2.png ├── sous_niveau_kPDTM_cov2.png ├── sublevf.png └── symbole_infini.png ├── LICENSE ├── README.Rmd ├── README.md ├── Tuto-GUDHI-Barycenters-of-persistence-diagrams.ipynb ├── Tuto-GUDHI-ConfRegions-PersDiag-datapoints.ipynb ├── Tuto-GUDHI-DTM-filtrations.ipynb ├── Tuto-GUDHI-Expected-persistence-diagrams.ipynb ├── Tuto-GUDHI-PyTorch-optimization.ipynb ├── Tuto-GUDHI-Quantization-of-persistence-diagrams.ipynb ├── Tuto-GUDHI-alpha-complex-visualization.ipynb ├── Tuto-GUDHI-cover-complex.ipynb ├── Tuto-GUDHI-cubical-complexes.ipynb ├── Tuto-GUDHI-extended-persistence.ipynb ├── Tuto-GUDHI-kPDTM-kPLM.ipynb ├── Tuto-GUDHI-optimization.ipynb ├── Tuto-GUDHI-persistence-diagrams.ipynb ├── Tuto-GUDHI-persistent-entropy.ipynb ├── Tuto-GUDHI-perslay-visu.ipynb ├── Tuto-GUDHI-representations.ipynb ├── Tuto-GUDHI-simplex-Trees.ipynb ├── Tuto-GUDHI-simplicial-complexes-from-data-points.ipynb ├── Tuto-GUDHI-simplicial-complexes-from-distance-matrix.ipynb ├── datasets ├── Corr_ProteinBinding │ ├── 1anf.corr_1.txt │ ├── 1ez9.corr_1.txt │ ├── 1fqa.corr_2.txt │ ├── 1fqb.corr_3.txt │ ├── 1fqc.corr_2.txt │ ├── 1fqd.corr_3.txt │ ├── 1jw4.corr_4.txt │ ├── 1jw5.corr_5.txt │ ├── 1lls.corr_6.txt │ ├── 1mpd.corr_4.txt │ ├── 1omp.corr_7.txt │ ├── 3hpi.corr_5.txt │ ├── 3mbp.corr_6.txt │ └── 4mbp.corr_7.txt ├── ElongatedTorus.txt ├── NoisyTrefoil180.txt ├── crater_tuto ├── data_acc ├── diff │ └── mnist_test.csv ├── human.off ├── human.txt ├── mnist_test.csv ├── tore3D_1307.off └── trefoil_dist ├── persistence_statistics.py └── utils ├── KeplerMapperVisuFromTxtFile.py ├── broken_links_scraper.py ├── utils_epd.py └── utils_quantization.py /.binder/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | pandas 3 | matplotlib 4 | seaborn 5 | scikit-learn 6 | tensorflow 7 | tensorflow-addons 8 | plotly 9 | pot 10 | networkx 11 | gudhi>=3.9.0 # Tuto-GUDHI-cover-complex.ipynb requires sklearn interfaces 12 | torch 13 | tqdm 14 | eagerpy 15 | -------------------------------------------------------------------------------- /.github/workflows/test_notebooks.yml: -------------------------------------------------------------------------------- 1 | name: Test notebooks 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Set up Python 3.8 12 | uses: actions/setup-python@v2 13 | with: 14 | python-version: 3.8 15 | - name: Install LaTeX support for matplotlib 16 | run: | 17 | sudo apt update 18 | sudo apt install -y ghostscript dvipng texlive-full 19 | - name: Install Python dependencies 20 | run: | 21 | python -m pip install --upgrade pip 22 | pip install -r .binder/requirements.txt 23 | pip install jupyter 24 | - name: Execute notebooks 25 | run: | 26 | for f in *.ipynb; do echo "Processing $f file.."; time jupyter nbconvert --to notebook --ExecutePreprocessor.timeout=600 --inplace --execute $f;done; 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .ipynb_checkpoints 3 | __pycache__ 4 | -------------------------------------------------------------------------------- /DTM_filtrations.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | import random 4 | import gudhi 5 | from sklearn.neighbors import KDTree 6 | from sklearn.metrics.pairwise import euclidean_distances 7 | import matplotlib.pyplot as plt 8 | from mpl_toolkits.mplot3d import Axes3D 9 | 10 | 11 | def DTM(X,query_pts,m): 12 | ''' 13 | Compute the values of the DTM (with exponent p=2) of the empirical measure of a point cloud X 14 | Require sklearn.neighbors.KDTree to search nearest neighbors 15 | 16 | Input: 17 | X: a nxd numpy array representing n points in R^d 18 | query_pts: a kxd numpy array of query points 19 | m: parameter of the DTM in [0,1) 20 | 21 | Output: 22 | DTM_result: a kx1 numpy array contaning the DTM of the 23 | query points 24 | 25 | Example: 26 | X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) 27 | Q = np.array([[0,0],[5,5]]) 28 | DTM_values = DTM(X, Q, 0.3) 29 | ''' 30 | N_tot = X.shape[0] 31 | k = math.floor(m*N_tot)+1 # number of neighbors 32 | 33 | kdt = KDTree(X, leaf_size=30, metric='euclidean') 34 | NN_Dist, NN = kdt.query(query_pts, k, return_distance=True) 35 | 36 | DTM_result = np.sqrt(np.sum(NN_Dist*NN_Dist,axis=1) / k) 37 | 38 | return(DTM_result) 39 | 40 | 41 | def WeightedRipsFiltrationValue(p, fx, fy, d, n = 10): 42 | ''' 43 | Computes the filtration value of the edge [x,y] in the weighted Rips filtration. 44 | If p is not 1, 2 or 'np.inf, an implicit equation is solved. 45 | The equation to solve is G(I) = d, where G(I) = (I**p-fx**p)**(1/p)+(I**p-fy**p)**(1/p). 46 | We use a dichotomic method. 47 | 48 | Input: 49 | p (float): parameter of the weighted Rips filtration, in [1, +inf) or np.inf 50 | fx (float): filtration value of the point x 51 | fy (float): filtration value of the point y 52 | d (float): distance between the points x and y 53 | n (int, optional): number of iterations of the dichotomic method 54 | 55 | Output: 56 | val (float): filtration value of the edge [x,y], i.e. solution of G(I) = d. 57 | 58 | Example: 59 | WeightedRipsFiltrationValue(2.4, 2, 3, 5, 10) 60 | ''' 61 | if p==np.inf: 62 | value = max([fx,fy,d/2]) 63 | else: 64 | fmax = max([fx,fy]) 65 | if d < (abs(fx**p-fy**p))**(1/p): 66 | value = fmax 67 | elif p==1: 68 | value = (fx+fy+d)/2 69 | elif p==2: 70 | value = np.sqrt( ( (fx+fy)**2 +d**2 )*( (fx-fy)**2 +d**2 ) )/(2*d) 71 | else: 72 | Imin = fmax; Imax = (d**p+fmax**p)**(1/p) 73 | for i in range(n): 74 | I = (Imin+Imax)/2 75 | g = (I**p-fx**p)**(1/p)+(I**p-fy**p)**(1/p) 76 | if g 136 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tutorials for Topological Data Analysis with the Gudhi Library 2 | 3 | Topological Data Analysis (TDA) is a recent and fast growing field 4 | providing a set of new topological and geometric tools to infer relevant 5 | features for possibly complex data. Here we propose a set of notebooks 6 | for the practice of TDA with the Python Gudhi library together with 7 | popular machine learning and data sciences libraries. See for instance 8 | [this paper](https://arxiv.org/abs/1710.04019) for an introduction to 9 | TDA for data science. The complete list of notebooks can also be found 10 | at the end of this page. 11 | 12 | ## Install Python Gudhi Library 13 | 14 | See the [installation 15 | page](https://gudhi.inria.fr/python/latest/installation.html) or 16 | if you have conda you can make a [conda 17 | install](https://anaconda.org/conda-forge/gudhi). 18 | 19 | ## TDA Analysis Pipeline 20 | 21 | ### 01 - Simplex trees and simpicial complexes 22 | 23 | TDA typically aims at extracting topological signatures from a point 24 | cloud in $\mathbb{R}^d$ or in a general metric space. By studying the topology 25 | of a point cloud, we actually mean studying the topology of the unions 26 | of balls centered at the point cloud, also called *offsets*. However, 27 | non-discrete sets such as offsets, and also continuous mathematical 28 | shapes like curves, surfaces and more generally manifolds, cannot easily 29 | be encoded as finite discrete structures. [Simplicial 30 | complexes](https://en.wikipedia.org/wiki/Simplicial_complex) are 31 | therefore used in computational geometry to approximate such shapes. 32 | 33 | A simplicial complex is a set of 34 | [simplices](https://en.wikipedia.org/wiki/Simplex), they can be seen as 35 | higher dimensional generalization of graphs. These are mathematical 36 | objects that are both topological and combinatorial, a property making 37 | them particularly useful for TDA. The challenge here is to define such 38 | structures that are proven to reflect relevant information about the 39 | structure of data and that can be effectively constructed and 40 | manipulated in practice. Below is an exemple of simplicial complex: 41 | 42 | ![simplicial complex example](Images/Pers14.PNG) 43 | 44 | A filtration is an increasing sequence of sub-complexes of a simplicial 45 | complex $\mathcal{K}$. It can be seen as ordering the simplices included in 46 | the complex $\mathcal{K}$. Indeed, simpicial complexes often come with a 47 | specific order, as for [Vietoris-Rips 48 | complexes](https://en.wikipedia.org/wiki/Vietoris%E2%80%93Rips_complex), 49 | [Cech complexes](https://en.wikipedia.org/wiki/%C4%8Cech_complex) and 50 | [alpha 51 | complexes](https://en.wikipedia.org/wiki/Alpha_shape#Alpha_complex). 52 | 53 | [Notebook: Simplex trees](Tuto-GUDHI-simplex-Trees.ipynb). In Gudhi, 54 | filtered simplicial complexes are encoded through a data structure 55 | called simplex tree. Vertices are represented as integers, edges as 56 | pairs of integers, etc. 57 | 58 | ![simplex tree representation](Images/Simplex_tree_representation.png) 59 | 60 | [Notebook: Vietoris-Rips complexes and alpha complexes from data 61 | points](https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-simplicial-complexes-from-data-points.ipynb). 62 | In practice, the first step of the **TDA Analysis Pipeline** is to define a 63 | filtration of simplicial complexes for some data. This notebook explains 64 | how to build Vietoris-Rips complexes and alpha complexes (represented as 65 | simplex trees) from data points in $\mathbb{R}^d$, using the simplex tree data 66 | structure. 67 | 68 | 69 | This [Notebook](Tuto-GUDHI-alpha-complex-visualization.ipynb) shows how to visualize simplicial complexes. 70 | 71 | 72 | [Notebook: Rips and alpha complexes from pairwise 73 | distance](Tuto-GUDHI-simplicial-complexes-from-distance-matrix.ipynb). 74 | It is also possible to define Rips complexes in general metric spaces 75 | from a matrix of pairwise distances. The definition of the metric on the 76 | data is usually given as an input or guided by the application. It is 77 | however important to notice that the choice of the metric may be 78 | critical to reveal interesting topological and geometric features of the 79 | data. We also give in this last notebook a way to define alpha complexes 80 | from matrix of pairwise distances by first applying a [multidimensional 81 | scaling (MDS)](https://en.wikipedia.org/wiki/Multidimensional_scaling) 82 | transformation on the matrix. 83 | 84 | TDA signatures can extracted from point clouds but in many cases in data 85 | sciences the question is to study the topology of the sublevel sets of a 86 | function. 87 | 88 | ![function exemple](Images/sublevf.png) 89 | 90 | Above is an example for a function defined on a subset of 91 | $\mathbb{R}$ but in general the function $f$ is defined on a subset of 92 | $\mathbb{R}^d$. 93 | 94 | [Notebook: cubical complexes](Tuto-GUDHI-cubical-complexes.ipynb). One 95 | first approach for studying the topology of the sublevel sets of a 96 | function is to define a regular grid on 97 | $\mathbb{R}^d$ and then to define a filtered complex based on this grid and the 98 | function $f$. 99 | 100 | ### 02 - Persistent homology and persistence diagrams 101 | 102 | Homology is a well-known concept in algebraic topology. It provides a 103 | powerful tool to formalize and handle the notion of topological features 104 | of a topological space or of a simplicial complex in an algebraic way. 105 | For any dimension $k$, the $k$-dimensional *holes* are represented by a vector 106 | space $H\_k$, whose dimension is intuitively the number of such independent 107 | features. For example, the $0$-dimensional homology group $H\_0$ represents the 108 | connected components of the complex, the $1$-dimensional homology group $H\_1$ 109 | represents the $1$-dimensional loops, the $2$-dimensional homology group $H\_2$ 110 | represents the $2$-dimensional cavities and so on. 111 | 112 | Persistent homology is a powerful tool to compute, study and encode 113 | efficiently multiscale topological features of nested families of 114 | simplicial complexes and topological spaces. It encodes the evolution of 115 | the homology groups of the nested complexes across the scales. The 116 | diagram below shows several level sets of the filtration: 117 | 118 | ![persistence](Images/pers.png) 119 | 120 | [Notebook: persistence diagrams](https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-persistence-diagrams.ipynb) 121 | In this notebook we show how to compute barcodes and persistence 122 | diagrams from a filtration defined on the Protein binding dataset. This 123 | tutorial also introduces the bottleneck distance between persistence 124 | diagrams. 125 | 126 | ### 03 - Representations of persistence and linearization 127 | 128 | In this [notebook](Tuto-GUDHI-representations.ipynb), we learn how to 129 | use alternative representations of persistence with the representations 130 | module and finally we see a first example of how to efficiently combine 131 | machine learning and topological data analysis. 132 | 133 | This [notebook](Tuto-GUDHI-Expected-persistence-diagrams.ipynb) 134 | illustrates the notion of “Expected Persistence Diagram”, which is a way 135 | to encode the topology of a random process as a deterministic measure. 136 | 137 | This [notebook](Tuto-GUDHI-persistent-entropy.ipynb) shows how to summarize 138 | the information given by persistent homology using persistent entropy (a 139 | number) and the ES-function (a curve) and explains in which situations they 140 | can be useful. 141 | 142 | ### 04 - Statistical tools for persistence 143 | 144 | For many applications of persistent homology, we observe topological 145 | features close to the diagonal. Since they correspond to topological 146 | structures that die very soon after they appear in the filtration, these 147 | points are generally considered as “topological noise”. Confidence 148 | regions for persistence diagram provide a rigorous framework to this 149 | idea. This [notebook](Tuto-GUDHI-ConfRegions-PersDiag-datapoints.ipynb) 150 | introduces the subsampling approach of [Fasy et al. 2014 151 | AoS](https://projecteuclid.org/download/pdfview_1/euclid.aos/1413810729). 152 | 153 | ### 05 - A Bayesian Framework for Persistent Homology 154 | 155 | C. Oballe and V. Maroulas provide a 156 | [tutorial](https://github.com/coballejr/misc/blob/master/Tuto-GUDHI-bayes-tda.ipynb) 157 | for a Python module that implements the model for Bayesian inference 158 | with persistence diagrams introduced in their 159 | [paper](https://epubs.siam.org/doi/pdf/10.1137/19M1268719). 160 | 161 | ### 06 - Machine learning and deep learning with TDA 162 | 163 | Two libraries related to Gudhi: 164 | 165 | - [ATOL](https://github.com/martinroyer/atol): Automatic 166 | Topologically-Oriented Learning. See [this 167 | tutorial](https://github.com/martinroyer/atol/blob/master/demo/atol-demo.ipynb). 168 | - [Perslay](https://github.com/MathieuCarriere/perslay): A Simple and 169 | Versatile Neural Network Layer for Persistence Diagrams. See [this 170 | notebook](Tuto-GUDHI-perslay-visu.ipynb). 171 | 172 | ### 07 - Alternative filtrations and robust TDA 173 | 174 | This [notebook](Tuto-GUDHI-DTM-filtrations.ipynb) introduces the 175 | distance to measure (DTM) filtration, as defined in [this 176 | paper](https://arxiv.org/abs/1811.04757). This filtration can be used 177 | for robust TDA. The DTM can also be used for robust approximations of 178 | compact sets, see this [notebook](Tuto-GUDHI-kPDTM-kPLM.ipynb). 179 | 180 | ### 08 - Topological Data Analysis for Time series 181 | 182 | ### 09 - Cover complexes and the Mapper Algorithm 183 | 184 | ### 10 - TDA and dimension reduction 185 | 186 | ### 11 - Inverse problem and optimization with TDA 187 | 188 | In this [notebook](Tuto-GUDHI-optimization.ipynb), we will see how Gudhi and 189 | Tensorflow can be combined to perform optimization of persistence diagrams to 190 | solve an inverse problem. This other, less complete 191 | [notebook](Tuto-GUDHI-PyTorch-optimization.ipynb) shows that this kind of 192 | optimization works just as well with PyTorch. 193 | 194 | ## Complete list of notebooks for TDA 195 | 196 | [Simplex trees](Tuto-GUDHI-simplex-Trees.ipynb) 197 | 198 | [Vietoris-Rips complexes and alpha complexes from data 199 | points](Tuto-GUDHI-simplicial-complexes-from-data-points.ipynb) 200 | 201 | [Visualizing simplicial 202 | complexes](Tuto-GUDHI-alpha-complex-visualization.ipynb) 203 | 204 | [Rips and alpha complexes from pairwise 205 | distance](Tuto-GUDHI-simplicial-complexes-from-distance-matrix.ipynb) 206 | 207 | [Cubical complexes](Tuto-GUDHI-cubical-complexes.ipynb) 208 | 209 | [Persistence diagrams and bottleneck 210 | distance](Tuto-GUDHI-persistence-diagrams.ipynb) 211 | 212 | [Representations of persistence](Tuto-GUDHI-representations.ipynb) 213 | 214 | [Expected Persistence 215 | Diagram](Tuto-GUDHI-Expected-persistence-diagrams.ipynb) 216 | 217 | [Confidence regions for persistence diagrams - data 218 | points](Tuto-GUDHI-ConfRegions-PersDiag-datapoints.ipynb) 219 | 220 | [ATOL 221 | tutorial](https://github.com/martinroyer/atol/blob/master/demo/atol-demo.ipynb) 222 | 223 | [Perslay](Tuto-GUDHI-perslay-visu.ipynb) 224 | 225 | [DTM-filtrations](Tuto-GUDHI-DTM-filtrations.ipynb) 226 | 227 | [kPDTM-kPLM](Tuto-GUDHI-kPDTM-kPLM.ipynb) 228 | 229 | [Inverse problem and optimization with TDA](Tuto-GUDHI-optimization.ipynb) 230 | 231 | [PyTorch differentiation of diagrams](Tuto-GUDHI-PyTorch-optimization.ipynb) 232 | 233 | Contact : 234 | -------------------------------------------------------------------------------- /Tuto-GUDHI-Expected-persistence-diagrams.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Expected persistence diagrams" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Theo Lacombe" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## A topological descriptor for a random process" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "This tutorial illustrates the notion of \"Expected Persistence Diagram\" introduced in a work of Chazal and Divol https://arxiv.org/pdf/1802.10457.pdf. In a nutshell, the expected persistence diagram encodes the topology of a *random* process as a *deterministic* measure. " 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "Recall that given an object $X$, say a point cloud embedded in the Euclidean space $\\mathbb{R}^d$, one can compute its persistence diagram $\\mathrm{Dgm}(X)$ which is a point cloud supported on a half-plane $\\Omega \\subset \\mathbb{R}^2$ (see this tutorial https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-persistence-diagrams.ipynb for an introduction to persistence diagrams).\n", 36 | "\n", 37 | "Now, consider that our point cloud is random. Here, we will consider that it consists of $n$ points sampled _i.i.d_ with respect to some law $\\xi$, thus denoted as $\\mathbb{X}_n = \\{X_1 \\cdots X_n\\}$, with $X_i \\sim \\xi$. To a *random* realization of $\\mathbb{X}_n$ corresponds a *random* persistence diagram. What can be said about this object? Can it be turn into a deterministic topological descriptor?\n", 38 | "\n", 39 | "As often, the simplest way to derive from a random object a deterministic summary is to consider its average behavior. Namely, for each compact $K$ included in the half-plane $\\Omega$, one can ask: _how many points of my (random) diagrams belong to $K$, on average?_. It leads to the following definition of **expected persistence diagram** of $\\mathbb{X}_n$, denoted by $\\mathbf{ED}(\\mathbb{X}_n)$:\n", 40 | "\n", 41 | "$$\\forall K \\subset \\Omega, \\mathbf{ED}(\\mathbb{X}_n)[K] := \\mathbb{E}({\\mathrm{Dgm}(\\mathbb{X}_n)}[K]),$$\n", 42 | "\n", 43 | "where $\\mathrm{Dgm}(\\mathbb{X}_n)[K]$ is, by definition, the (random) number of points in $\\mathrm{Dgm}(\\mathbb{X}_n)$ that belong to $K$." 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "Chazal and Divol proved (under mild assumptions) that $\\mathbb{ED}(\\mathbb{X}_n)$ is a deterministic measure which has a density with respect to the Lebesgue measure on $\\Omega$. Later, Divol and Lacombe (see https://arxiv.org/pdf/1901.03048.pdf) showed that $\\mathbf{ED}(\\mathbb{X}_n)$ is stable with respect to $\\xi$, which states that point clouds sampled from similar random processes must have similar expected persistence diagrams." 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "## A numerical illustration" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "Theoretically computing $\\mathbf{ED}(\\mathbb{X}_n)$ cannot be done. In practice, one is more likely to have access to some observations $(\\mathbb{X}_n^{(k)})_k \\in \\mathbb{R}^{d \\times n \\times n_\\mathrm{obs}}$, $k = 1 \\dots n_\\mathrm{obs}$. As usual, the empirical (arithmetic) mean converges to the expectation, that is\n", 65 | "$$\\lim_{n_\\mathrm{obs} \\to \\infty} \\frac{1}{n_\\mathrm{obs}} \\sum_{k=1}^{n_\\mathrm{obs}} \\mathrm{Dgm}(\\mathbb{X}_n^{(k)}) = \\mathbf{ED}(\\mathbb{X}_n).$$\n", 66 | "\n", 67 | "Here, the sum of diagrams must be understood as a sum of measures. Briefly, it consists in taking the union of points in each diagram $\\mathrm{Dgm}(\\mathbb{X}_n^{(k)})$ (counted with multiplicity), and dividing the multiplicities (viewed as a weight) by $n_\\mathrm{obs}$." 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "#### Experiment overview" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "We will showcase expected diagrams in the following context:\n", 82 | "- Consider a point cloud $X$ with $n_\\mathrm{tot}$ points, which splits in $(1-p)n_\\mathrm{tot}$ points sampled on a nice shape $\\mathcal{M}$ (here, a 3D torus or a 1D circle), and $p n_\\mathrm{tot}$ outliers, where $p \\in (0,1)$ is the proportion of outliers. Let us call $X_\\mathrm{true}$ and $X_\\mathrm{out}$ these two point clouds.\n", 83 | "- Computing directly the (alpha complex) diagram of the whole point cloud $X$ won't reflect the topology of $\\mathcal{M}$ in general, due to the presence of outliers. However, if $p$ is small enough, one can expect that by sampling $n < n_\\mathrm{tot}$ points on $X$, we will avoid sampling outliers with high probability. We will thus recover a diagram close to $\\mathrm{Dgm}(X_\\mathrm{true})$ \"most of the time\", provided we sampled enough points.\n", 84 | "- Repeating this process, and then averaging, we obtain (an estimator of) $\\mathbf{ED}(\\mathbb{X}_n)$.\n", 85 | "- As the random processes $\\mathbb{X}_n$ and $(\\mathbb{X}_\\mathrm{true})_n$ (sampling $n$ points on $X$ and on $X_\\mathrm{true}$ respectively) are similar (in Wasserstein sense), so should be their expected diagrams. " 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "#### Imports" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 1, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "# Note: %matplotlib notebook enables iteractive 3D plot.\n", 102 | "#%matplotlib notebook\n", 103 | "%matplotlib inline" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 2, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "import numpy as np\n", 113 | "import gudhi as gd\n", 114 | "import matplotlib.pyplot as plt\n", 115 | "\n", 116 | "# A collection of utils functions for this notebook\n", 117 | "import utils.utils_epd as uepd\n", 118 | "\n", 119 | "# Comment this if you don't want to use LaTeX in matplotlib rendering.\n", 120 | "from matplotlib import rc\n", 121 | "plt.rc('text', usetex=True)\n", 122 | "plt.rc('font', family='serif')" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "### Numerical illustration" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 3, 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "name": "stdout", 139 | "output_type": "stream", 140 | "text": [ 141 | "Number of point on the shape: 9990\n", 142 | "Number of points corresponding to noise: 10\n", 143 | "Proportion of noise: 0.001\n", 144 | "Total number of points: 10000\n" 145 | ] 146 | } 147 | ], 148 | "source": [ 149 | "nb_tot = 10000\n", 150 | "prop_noise = 0.001\n", 151 | "\n", 152 | "nb_points = int((1 - prop_noise) * nb_tot)\n", 153 | "nb_noise = nb_tot - nb_points\n", 154 | "\n", 155 | "print(\"Number of point on the shape:\", nb_points)\n", 156 | "print(\"Number of points corresponding to noise:\", nb_noise)\n", 157 | "print(\"Proportion of noise:\", prop_noise)\n", 158 | "print(\"Total number of points:\", nb_tot)" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 4, 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "# X = sample_torus(nb_points, r1 = 3, r2 = 1)\n", 168 | "X = uepd.sample_circle(nb_points)\n", 169 | "X_noise = uepd.sample_noise(nb_noise, \n", 170 | " ndim = X.shape[1], \n", 171 | " scale = np.std(X),\n", 172 | " type=\"uniform\")\n", 173 | "X_tot = uepd.add_noise(X_noise, X)" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 5, 179 | "metadata": {}, 180 | "outputs": [ 181 | { 182 | "data": { 183 | "image/png": "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\n", 184 | "text/plain": [ 185 | "
" 186 | ] 187 | }, 188 | "metadata": { 189 | "needs_background": "light" 190 | }, 191 | "output_type": "display_data" 192 | } 193 | ], 194 | "source": [ 195 | "uepd.plot_object(X, X_noise)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 6, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "dgm_tot = uepd.alphacomplex(X_tot)\n", 205 | "dgm_true = uepd.alphacomplex(X)" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 7, 211 | "metadata": {}, 212 | "outputs": [], 213 | "source": [ 214 | "nb_points_samples = 100\n", 215 | "nb_repeat = 100" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": 8, 221 | "metadata": {}, 222 | "outputs": [], 223 | "source": [ 224 | "# Resolution parameters\n", 225 | "m=-0.1\n", 226 | "M=1.1" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 9, 232 | "metadata": {}, 233 | "outputs": [], 234 | "source": [ 235 | "diags = uepd.expected_dgm(X_tot, nb_points_samples, nb_repeat)\n", 236 | "h = uepd.tohist(diags, m=m, M=M)" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 10, 242 | "metadata": {}, 243 | "outputs": [ 244 | { 245 | "data": { 246 | "image/png": "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\n", 247 | "text/plain": [ 248 | "
" 249 | ] 250 | }, 251 | "metadata": { 252 | "needs_background": "light" 253 | }, 254 | "output_type": "display_data" 255 | } 256 | ], 257 | "source": [ 258 | "fig = plt.figure(figsize=(12,6))\n", 259 | "ax1 = fig.add_subplot(121)\n", 260 | "ax2 = fig.add_subplot(122)\n", 261 | "uepd.plot_dgm(dgm_true, dgm_tot, m = m, M=M, ax=ax1)\n", 262 | "uepd.plot_hist(h, ax=ax2)" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "As one can see, the expected persistence diagram is much more similar to the true diagram (blue point) than the diagram one would obtain by considering the whole point cloud directly (red crosses)!" 270 | ] 271 | } 272 | ], 273 | "metadata": { 274 | "kernelspec": { 275 | "display_name": "Python 3", 276 | "language": "python", 277 | "name": "python3" 278 | }, 279 | "language_info": { 280 | "codemirror_mode": { 281 | "name": "ipython", 282 | "version": 3 283 | }, 284 | "file_extension": ".py", 285 | "mimetype": "text/x-python", 286 | "name": "python", 287 | "nbconvert_exporter": "python", 288 | "pygments_lexer": "ipython3", 289 | "version": "3.8.2" 290 | } 291 | }, 292 | "nbformat": 4, 293 | "nbformat_minor": 2 294 | } 295 | -------------------------------------------------------------------------------- /Tuto-GUDHI-simplex-Trees.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "# Topological Data Analysis with Python and the Gudhi Library \n", 10 | "\n", 11 | "# Introduction to simplex trees " 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "**Authors** : F. Chazal and B. Michel" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "TDA typically aims at extracting topological signatures from a point cloud in $\\mathbb R^d$ or in a general metric space. By studying the topology of the point clouds, we actually mean studying the topology of unions of balls centered at the point cloud (offsets). However, non-discrete sets such as offsets, and also continuous mathematical shapes like curves, surfaces and more generally manifolds, cannot easily be encoded as finite discrete structures. [Simplicial complexes](https://en.wikipedia.org/wiki/Simplicial_complex) are therefore used in computational geometry to approximate such shapes.\n", 26 | "\n", 27 | "A simplicial complex is a set of [simplices](https://en.wikipedia.org/wiki/Simplex). It can be seen as a higher dimensional generalization of a graph. It is a mathematical object that is both topological and combinatorial, which makes it particularly useful for TDA. Here is an exemple of simplicial complex:\n", 28 | "\n", 29 | "![title](Images/Pers14.PNG)\n", 30 | " \n", 31 | "A filtration is a increasing sequence of sub-complexes of a simplicial complex $\\mathcal K$. It can be seen as ordering the simplices included in the complex. Indeed, simpicial complexes often come with a specific order, as for [Vietoris-Rips complexes](https://en.wikipedia.org/wiki/Vietoris%E2%80%93Rips_complex), [Cech complexes](https://en.wikipedia.org/wiki/%C4%8Cech_complex) and [alpha complexes](https://en.wikipedia.org/wiki/Alpha_shape#Alpha_complex). " 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 1, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "from IPython.display import Image\n", 41 | "from os import chdir\n", 42 | "import numpy as np\n", 43 | "import gudhi as gd\n", 44 | "import matplotlib.pyplot as plt" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "In Gudhi, filtered simplicial complexes are encoded through a data structure called simplex tree. \n", 52 | "![](https://gudhi.inria.fr/python/latest/_images/Simplex_tree_representation.png)\n", 53 | "\n", 54 | "This notebook illustrates the use of simplex tree to represent simplicial complexes from data points.\n", 55 | "\n", 56 | "See the [Python Gudhi documentation](https://gudhi.inria.fr/python/latest/simplex_tree_ref.html#) for more details on simplex trees." 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "### My first simplex tree" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "Let's create our first simplicial complex, represented by a simplex tree :" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 2, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "st = gd.SimplexTree()" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "The `st` object has class `SimplexTree`. For now, `st` is an empty simplex tree.\n", 87 | "\n", 88 | "The `SimplexTree` class has several useful methods for the practice of TDA. For instance, there are methods to define new types of simplicial complexes from existing ones.\n", 89 | "\n", 90 | "The `insert()` method can be used to insert simplices in the simplex tree. In the simplex tree:\n", 91 | "\n", 92 | "- vertices (0-dimensional simplices) are represented with integers, \n", 93 | "- edges (1-dimensional simplices) are represented with a length-2 list of integers (corresponding to the two vertices involved in the edge),\n", 94 | "- triangles (2-dimensional simplices) by three integers are represented with a length-3 list of integers (corresponding to the three vertices involved in the triangle),\n", 95 | "- etc.\n", 96 | "\n", 97 | "For example, the following piece of code inserts three edges into the simplex tree:" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 22, 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "False" 109 | ] 110 | }, 111 | "execution_count": 22, 112 | "metadata": {}, 113 | "output_type": "execute_result" 114 | } 115 | ], 116 | "source": [ 117 | "st.insert([0, 1])\n", 118 | "st.insert([1, 2])\n", 119 | "st.insert([3, 1])" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "When the simplex is successfully inserted into the simplex tree, the `insert()` method outputs `True` as you can see from the execution of the above code. On the contrary, if the simplex is already in the filtration, the `insert()` method outputs `False`:" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 23, 132 | "metadata": {}, 133 | "outputs": [ 134 | { 135 | "data": { 136 | "text/plain": [ 137 | "False" 138 | ] 139 | }, 140 | "execution_count": 23, 141 | "metadata": {}, 142 | "output_type": "execute_result" 143 | } 144 | ], 145 | "source": [ 146 | "st.insert([3, 1])" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "We obtain the list of all the simplices in the simplex tree with the `get_filtration()` method : " 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 5, 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [ 162 | "st_gen = st.get_filtration() " 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": {}, 168 | "source": [ 169 | "The output `st_gen` is a generator and we thus we can iterate on its elements. Each element in the list is a tuple that contains a simplex and its **filtration value**." 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 6, 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "name": "stdout", 179 | "output_type": "stream", 180 | "text": [ 181 | "([0], 0.0)\n", 182 | "([1], 0.0)\n", 183 | "([0, 1], 0.0)\n", 184 | "([2], 0.0)\n", 185 | "([1, 2], 0.0)\n", 186 | "([3], 0.0)\n", 187 | "([1, 3], 0.0)\n" 188 | ] 189 | } 190 | ], 191 | "source": [ 192 | "for splx in st_gen :\n", 193 | " print(splx)" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "Intuitively, the filtration value of a simplex in a filtered complex acts as a *time stamp* corresponding to \"when\" the simplex appears in the filtration. By default, the `insert()` method assigns a filtration value equal to 0.\n", 201 | "\n", 202 | "Notice that inserting an edge automatically inserts its vertices (if they were not already in the complex) in order to satisfy the **inclusion property** of a filtered complex: any simplex with filtration value $t$ must have all its faces in the filtered complex, with filtration values smaller than or equal to $t$." 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "### Simplex tree description" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": {}, 215 | "source": [ 216 | "The dimension of a simplical complex is the largest dimension of the simplices in it. It can be retrieved by the simplex tree `dimension()` method:" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 7, 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "data": { 226 | "text/plain": [ 227 | "1" 228 | ] 229 | }, 230 | "execution_count": 7, 231 | "metadata": {}, 232 | "output_type": "execute_result" 233 | } 234 | ], 235 | "source": [ 236 | "st.dimension()" 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": {}, 242 | "source": [ 243 | "It is possible to compute the number of vertices in a simplex tree via the `num_vertices()` method:" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 10, 249 | "metadata": {}, 250 | "outputs": [ 251 | { 252 | "data": { 253 | "text/plain": [ 254 | "4" 255 | ] 256 | }, 257 | "execution_count": 10, 258 | "metadata": {}, 259 | "output_type": "execute_result" 260 | } 261 | ], 262 | "source": [ 263 | "st.num_vertices()" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "The number of simplices in the simplex tree is given by" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 9, 276 | "metadata": {}, 277 | "outputs": [ 278 | { 279 | "data": { 280 | "text/plain": [ 281 | "7" 282 | ] 283 | }, 284 | "execution_count": 9, 285 | "metadata": {}, 286 | "output_type": "execute_result" 287 | } 288 | ], 289 | "source": [ 290 | "st.num_simplices()" 291 | ] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "metadata": {}, 296 | "source": [ 297 | "The [$d$-skeleton](https://en.wikipedia.org/wiki/N-skeleton) -- which is the union of all simplices of dimensions smaller than or equal to $d$ -- can be also computed with the `get_skeleton()` method. This method takes as argument the dimension of the desired skeleton. To retrieve the topological graph from a simplex tree, we can therefore call:" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": 18, 303 | "metadata": { 304 | "scrolled": true 305 | }, 306 | "outputs": [ 307 | { 308 | "name": "stdout", 309 | "output_type": "stream", 310 | "text": [ 311 | "[([0, 1], 0.0), ([0], 0.0), ([1, 2], 0.0), ([1, 3], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0)]\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "print(st.get_skeleton(1))" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "One can also check whether a simplex is already in the filtration. This is achieved with the `find()` method:" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": 19, 329 | "metadata": {}, 330 | "outputs": [ 331 | { 332 | "data": { 333 | "text/plain": [ 334 | "False" 335 | ] 336 | }, 337 | "execution_count": 19, 338 | "metadata": {}, 339 | "output_type": "execute_result" 340 | } 341 | ], 342 | "source": [ 343 | "st.find([2, 4])" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "### Filtration values\n", 351 | "\n", 352 | "We can insert simplices at a given filtration value. For example, the following piece of code will insert three triangles in the simplex tree at three different filtration values:" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 24, 358 | "metadata": {}, 359 | "outputs": [ 360 | { 361 | "name": "stdout", 362 | "output_type": "stream", 363 | "text": [ 364 | "([0], 0.0)\n", 365 | "([1], 0.0)\n", 366 | "([0, 1], 0.0)\n", 367 | "([2], 0.0)\n", 368 | "([1, 2], 0.0)\n", 369 | "([3], 0.0)\n", 370 | "([1, 3], 0.0)\n", 371 | "([0, 2], 0.1)\n", 372 | "([0, 1, 2], 0.1)\n", 373 | "([2, 3], 0.2)\n", 374 | "([1, 2, 3], 0.2)\n", 375 | "([0, 3], 0.4)\n", 376 | "([0, 1, 3], 0.4)\n" 377 | ] 378 | } 379 | ], 380 | "source": [ 381 | "st.insert([0, 1, 2], filtration = 0.1)\n", 382 | "st.insert([1, 2, 3], filtration = 0.2)\n", 383 | "st.insert([0, 1, 3], filtration = 0.4)\n", 384 | "st_gen = st.get_filtration() \n", 385 | "\n", 386 | "for splx in st_gen :\n", 387 | " print(splx)" 388 | ] 389 | }, 390 | { 391 | "cell_type": "markdown", 392 | "metadata": {}, 393 | "source": [ 394 | "As you can see, when we add a new simplex with a given filtration value, all its faces that were not already in the complex are added with the same filtration value: here the edge `[0, 3]` was not part of the tree before including the triangle `[0, 1, 3]` and is thus inserted with the filtration value of the inserted triangle. On the other hand, the filtration value of the faces of added simplices that were already part of the tree before is left alone. One can modify the filtration value of any simplex included in the tree with the `assign_filtration()` method:" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": 26, 400 | "metadata": {}, 401 | "outputs": [ 402 | { 403 | "name": "stdout", 404 | "output_type": "stream", 405 | "text": [ 406 | "([0], 0.0)\n", 407 | "([1], 0.0)\n", 408 | "([0, 1], 0.0)\n", 409 | "([2], 0.0)\n", 410 | "([1, 2], 0.0)\n", 411 | "([1, 3], 0.0)\n", 412 | "([0, 2], 0.1)\n", 413 | "([0, 1, 2], 0.1)\n", 414 | "([2, 3], 0.2)\n", 415 | "([1, 2, 3], 0.2)\n", 416 | "([0, 3], 0.4)\n", 417 | "([0, 1, 3], 0.4)\n", 418 | "([3], 0.8)\n" 419 | ] 420 | } 421 | ], 422 | "source": [ 423 | "st.assign_filtration([3], filtration = 0.8)\n", 424 | "st_gen = st.get_filtration()\n", 425 | "for splx in st_gen:\n", 426 | " print(splx) " 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "Notice that, the vertex `[3]` has been moved to the end of the filtration because it now has the highest filtration value. However, this simplex tree is not a filtered simplicial complex anymore because the filtration value of the vertex `[3]` is higher than the filtration value of the edge `[2 3]`. We can use the `make_filtration_non_decreasing()` method to solve the problem:" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": 27, 439 | "metadata": {}, 440 | "outputs": [ 441 | { 442 | "name": "stdout", 443 | "output_type": "stream", 444 | "text": [ 445 | "([0], 0.0)\n", 446 | "([1], 0.0)\n", 447 | "([0, 1], 0.0)\n", 448 | "([2], 0.0)\n", 449 | "([1, 2], 0.0)\n", 450 | "([0, 2], 0.1)\n", 451 | "([0, 1, 2], 0.1)\n", 452 | "([3], 0.8)\n", 453 | "([0, 3], 0.8)\n", 454 | "([1, 3], 0.8)\n", 455 | "([0, 1, 3], 0.8)\n", 456 | "([2, 3], 0.8)\n", 457 | "([1, 2, 3], 0.8)\n" 458 | ] 459 | } 460 | ], 461 | "source": [ 462 | "st.make_filtration_non_decreasing()\n", 463 | "st_gen = st.get_filtration()\n", 464 | "for splx in st_gen:\n", 465 | " print(splx) " 466 | ] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": {}, 471 | "source": [ 472 | "Finally, it is worth mentioning the `filtration()` method, which returns the filtration value of a given simplex in the filtration :" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 29, 478 | "metadata": {}, 479 | "outputs": [ 480 | { 481 | "data": { 482 | "text/plain": [ 483 | "0.8" 484 | ] 485 | }, 486 | "execution_count": 29, 487 | "metadata": {}, 488 | "output_type": "execute_result" 489 | } 490 | ], 491 | "source": [ 492 | "st.filtration([2, 3])" 493 | ] 494 | } 495 | ], 496 | "metadata": { 497 | "anaconda-cloud": {}, 498 | "kernelspec": { 499 | "display_name": "Python 3 (ipykernel)", 500 | "language": "python", 501 | "name": "python3" 502 | }, 503 | "language_info": { 504 | "codemirror_mode": { 505 | "name": "ipython", 506 | "version": 3 507 | }, 508 | "file_extension": ".py", 509 | "mimetype": "text/x-python", 510 | "name": "python", 511 | "nbconvert_exporter": "python", 512 | "pygments_lexer": "ipython3", 513 | "version": "3.9.0" 514 | }, 515 | "toc": { 516 | "base_numbering": 1, 517 | "nav_menu": {}, 518 | "number_sections": true, 519 | "sideBar": true, 520 | "skip_h1_title": false, 521 | "title_cell": "Table of Contents", 522 | "title_sidebar": "Contents", 523 | "toc_cell": false, 524 | "toc_position": {}, 525 | "toc_section_display": true, 526 | "toc_window_display": false 527 | } 528 | }, 529 | "nbformat": 4, 530 | "nbformat_minor": 1 531 | } 532 | -------------------------------------------------------------------------------- /datasets/NoisyTrefoil180.txt: -------------------------------------------------------------------------------- 1 | -2.1979500e+00 -9.4310506e-02 9.2208926e-01 2 | 4.9506327e-02 -1.0768608e+00 7.4059901e-02 3 | -6.4328027e-01 -2.7638850e+00 -6.1968416e-01 4 | -1.1486909e+00 -2.0764359e+00 -1.0219290e+00 5 | -7.6588907e-01 -2.7144399e+00 -5.4098733e-01 6 | -1.5140760e+00 2.0830947e+00 -9.0111640e-01 7 | -6.2053576e-01 8.0686845e-01 2.1801783e-01 8 | -1.8240774e+00 2.0107895e+00 -8.3204958e-01 9 | -4.9631027e-01 -2.8856513e+00 -5.6730095e-01 10 | 1.0413570e+00 -8.5602842e-01 -7.1262422e-01 11 | 2.5017323e+00 1.6850439e+00 1.5154592e-01 12 | -2.5929115e-01 1.6061931e+00 -9.1427255e-01 13 | -5.5636158e-01 -2.8865317e+00 -4.4684229e-01 14 | 2.7161988e+00 1.2700904e+00 -2.7573043e-01 15 | -9.9007891e-01 2.5148192e-01 -5.7885109e-02 16 | 1.2795482e+00 -1.1960074e+00 9.7447345e-01 17 | 2.2686733e+00 1.8419515e+00 4.6351042e-01 18 | -8.0233157e-01 1.8593193e+00 -9.9043792e-01 19 | 1.0720596e+00 2.0449119e+00 1.0485390e+00 20 | -2.2771689e+00 -1.6145893e-01 9.4257263e-01 21 | 4.6880805e-01 1.8029218e+00 9.6982726e-01 22 | -1.4410124e+00 2.0238504e+00 -9.9107721e-01 23 | 2.2337909e+00 1.8137126e+00 3.8280939e-01 24 | 7.8843917e-02 1.4562932e+00 7.2683821e-01 25 | 2.2834032e+00 -5.5130735e-03 -9.6048440e-01 26 | 1.1804753e+00 -2.0655541e+00 9.5209286e-01 27 | 6.1151800e-01 8.8665988e-01 -3.6273120e-01 28 | 8.1654223e-01 -2.5916828e+00 7.9727768e-01 29 | -1.1526385e+00 -2.1201302e+00 -1.0066175e+00 30 | 1.1336894e+00 -1.0483482e-01 4.2484464e-01 31 | 1.0454985e+00 9.7836071e-03 3.3380538e-01 32 | 6.5228996e-01 8.1650589e-01 -2.1721969e-01 33 | 1.2763248e+00 -3.7343582e-01 4.2153466e-01 34 | -1.5222694e+00 -5.7058548e-01 8.8235995e-01 35 | 1.9322645e+00 1.9906782e+00 8.0775756e-01 36 | -6.9529397e-02 1.5178299e+00 -6.6766914e-01 37 | 1.3489163e+00 1.9934144e+00 1.0120510e+00 38 | 2.6956334e+00 6.4636010e-01 -7.8970393e-01 39 | 1.3151244e+00 -1.2717722e+00 9.0869720e-01 40 | -9.2202055e-01 -2.6628310e+00 -7.9527618e-01 41 | -6.3379746e-01 -2.6342935e+00 -6.9704090e-01 42 | 8.1951671e-01 3.6691874e-01 4.7365099e-02 43 | -1.5217138e+00 2.0849282e+00 -9.4539446e-01 44 | -1.1616693e+00 5.7647445e-03 -3.2166145e-01 45 | 9.0474211e-01 3.2082957e-01 6.3638299e-02 46 | -1.2197455e+00 -2.0069954e+00 -9.5811231e-01 47 | -2.6606330e+00 1.3847776e+00 2.8823683e-01 48 | -2.6296607e+00 1.4924496e+00 -7.4017741e-02 49 | 8.7632828e-01 1.9431263e+00 9.9905589e-01 50 | 1.3561032e+00 -1.0251895e+00 7.7091975e-01 51 | 1.2565464e+00 -1.9638828e+00 1.0649166e+00 52 | 7.0528046e-01 -2.7474758e+00 7.6513491e-01 53 | -2.6727530e+00 8.6870346e-01 5.5344001e-01 54 | 6.5942113e-01 1.9027748e+00 1.0586316e+00 55 | -4.7437285e-01 8.3290355e-01 2.2944569e-01 56 | 2.7288309e+00 4.7689851e-01 -7.6852492e-01 57 | -1.6834898e+00 -5.5418082e-01 9.6113746e-01 58 | 1.1440438e+00 -8.8661581e-02 3.9493898e-01 59 | -4.4617588e-01 -2.8783348e+00 -2.6272971e-01 60 | 1.1813872e+00 -2.7815216e-01 6.3062376e-01 61 | 7.5045522e-01 -2.7093736e+00 7.5347743e-01 62 | 1.0947325e+00 -3.2628380e-02 2.6144341e-01 63 | 8.0340310e-01 -2.7243326e+00 7.1780974e-01 64 | -2.9960827e-01 1.6401092e+00 -8.9713941e-01 65 | 3.7224123e-01 -2.9433348e+00 3.7319604e-01 66 | -2.1806616e-01 -1.0559967e+00 6.2002000e-02 67 | 1.7397210e+00 2.0290468e+00 8.3460994e-01 68 | 2.5793874e+00 2.6415084e-01 -8.0634355e-01 69 | 2.5514619e+00 3.7521044e-01 -9.1483206e-01 70 | 1.8383509e+00 -4.9657325e-01 -9.4558178e-01 71 | -1.2952479e+00 -1.5725079e+00 -9.1583543e-01 72 | -8.2346287e-01 -2.5666857e+00 -7.6601994e-01 73 | -1.2506446e+00 -3.7318238e-01 -5.5046359e-01 74 | -1.3409080e+00 2.0865351e+00 -9.1647425e-01 75 | 1.2202504e+00 -6.1839063e-01 7.1100387e-01 76 | -1.6051711e+00 1.9885107e+00 -9.3447797e-01 77 | -1.8882940e+00 -4.9825122e-01 9.7525678e-01 78 | -8.5468985e-01 -9.9667264e-01 4.7655347e-01 79 | 2.2910718e+00 1.9788620e+00 4.1506097e-01 80 | 2.6910316e+00 1.0384099e+00 -4.6850245e-01 81 | 4.0204429e-01 1.2427255e+00 -5.2606759e-01 82 | 2.4104794e+00 1.8772490e-02 -9.8988294e-01 83 | 5.2110034e-01 -2.9435536e+00 4.7535561e-01 84 | 5.4343447e-01 -2.8108486e+00 5.9067852e-01 85 | -2.7437942e+00 1.0677659e+00 5.2011516e-01 86 | -2.4885452e-01 -3.0440225e+00 -2.7191729e-01 87 | -1.2981198e+00 -1.2663548e+00 -8.9182276e-01 88 | 7.3249502e-01 6.2377878e-01 -8.7126509e-02 89 | -8.5585630e-01 1.8334436e+00 -1.0251771e+00 90 | 3.1810321e-01 -2.8868490e+00 4.0838299e-01 91 | -1.1369734e+00 7.5613469e-02 -1.9729225e-01 92 | 2.7141197e+00 1.3013766e+00 -3.3577115e-01 93 | 1.2301724e+00 -1.8161396e+00 1.0950362e+00 94 | 6.7462771e-01 1.9209734e+00 9.6509652e-01 95 | 1.2676916e+00 -7.9184411e-01 -7.5545402e-01 96 | -1.0844484e+00 1.9959065e+00 -1.0405596e+00 97 | 1.2020187e+00 1.9786653e+00 9.5115038e-01 98 | -9.7489655e-01 -2.4141955e+00 -9.3227449e-01 99 | 5.3541104e-01 1.1035936e+00 -3.7013841e-01 100 | -1.2309512e+00 -2.6956383e-01 -3.8910341e-01 101 | -6.3395616e-01 1.9067029e+00 -9.4066034e-01 102 | -1.3072012e+00 -1.3045007e+00 -8.7284071e-01 103 | 5.8860734e-01 9.3864453e-01 -2.4340387e-01 104 | 9.6721071e-02 1.4507860e+00 -7.7271403e-01 105 | -9.5532790e-01 -2.4259805e+00 -8.9385395e-01 106 | 5.8404661e-01 -9.9917733e-01 -3.4305968e-01 107 | -8.7123550e-01 5.2406192e-01 8.2506948e-02 108 | -1.2304850e+00 -2.0590087e+00 -1.0548833e+00 109 | 5.3983125e-01 1.7988627e+00 8.7759450e-01 110 | 2.1375321e+00 1.8566897e+00 5.8150792e-01 111 | -2.4770530e+00 1.6857941e+00 -2.2296880e-01 112 | -1.1764913e+00 -2.1146157e+00 -9.4129601e-01 113 | -2.6373088e+00 4.2935897e-01 8.0726538e-01 114 | -1.4887091e+00 -1.1893838e+00 -9.6852065e-01 115 | -1.5229355e+00 1.9523162e+00 -8.9773189e-01 116 | -1.3928267e+00 -1.3765908e+00 -8.7097489e-01 117 | -2.3255292e+00 1.7730103e+00 -3.6934909e-01 118 | -1.1376695e+00 2.0085141e+00 -1.0720336e+00 119 | -1.3189773e+00 -7.5158761e-01 -8.0514717e-01 120 | 1.9028317e+00 2.1084633e+00 7.2808780e-01 121 | -1.9689956e+00 2.0887520e+00 -7.2577586e-01 122 | -1.5153540e+00 -6.6383747e-01 7.8588407e-01 123 | -8.4997756e-01 6.3850328e-01 1.7421601e-01 124 | 7.6744110e-01 6.6444637e-01 -1.5930956e-01 125 | -1.0845915e+00 -2.3365153e+00 -1.0025232e+00 126 | -2.5981334e+00 1.5355297e+00 1.3418048e-02 127 | -1.4197750e+00 2.1012283e+00 -8.7786285e-01 128 | 2.6127048e+00 1.4355344e+00 -2.9078975e-02 129 | -2.7708449e+00 9.9973905e-01 4.5084214e-01 130 | -3.9897328e-01 -9.9042511e-01 1.8228136e-01 131 | 3.4301887e-01 -3.0011471e+00 1.8671643e-01 132 | -2.5486047e+00 4.7970709e-01 8.2025450e-01 133 | 1.2686875e+00 -1.6830167e+00 1.0375097e+00 134 | 2.6385451e+00 1.2533413e+00 -2.1180963e-01 135 | 2.1890363e+00 1.8640008e+00 4.9022915e-01 136 | -1.3186579e+00 -1.6048902e+00 -1.0101317e+00 137 | -9.9092999e-01 2.0921419e+00 -1.0148040e+00 138 | -2.4716312e+00 1.6222019e+00 -5.4876923e-02 139 | -2.0005949e+00 2.0169407e+00 -6.8370290e-01 140 | -7.0622254e-01 8.3892177e-01 2.7267955e-01 141 | 6.3885103e-01 -2.7130153e+00 6.6434156e-01 142 | 2.3647280e+00 -1.9366795e-03 -1.0444676e+00 143 | 2.6225579e+00 4.5757351e-01 -8.7778018e-01 144 | 2.7601876e+00 8.9045594e-01 -4.7113953e-01 145 | 7.1531762e-01 8.5784444e-01 -1.4888779e-01 146 | -4.2319102e-02 -2.9764115e+00 -5.4267073e-02 147 | 2.2750674e+00 1.7649610e+00 4.4537139e-01 148 | -5.3562148e-02 -2.9935833e+00 -1.2330531e-01 149 | 2.7285819e+00 1.1379400e+00 -3.1432088e-01 150 | 1.5876552e+00 -5.9504240e-01 -9.0190161e-01 151 | -2.7736138e+00 1.1798490e+00 3.5049087e-01 152 | 1.0402689e+00 -2.3862465e+00 9.2335934e-01 153 | -1.9929567e+00 -4.1512601e-01 1.0273556e+00 154 | 3.0022930e-01 1.2223672e+00 -5.5712868e-01 155 | 1.1885018e+00 -1.8411796e+00 1.0317547e+00 156 | -2.4590392e+00 1.8484707e+00 -2.9202497e-01 157 | -2.6779275e+00 5.6584968e-01 7.1361388e-01 158 | -3.5050153e-01 -8.6417096e-01 2.1530488e-01 159 | 7.6362200e-02 -9.2365840e-01 7.0016311e-02 160 | -2.6937814e+00 9.1152848e-01 5.7452376e-01 161 | 1.3785370e+00 -1.0864138e+00 8.3655360e-01 162 | -3.5245462e-01 -1.0209978e+00 2.1113619e-01 163 | 4.6187231e-01 -2.8234994e+00 4.8464910e-01 164 | -4.4412372e-01 -2.9606178e+00 -3.5430549e-01 165 | -2.1263081e+00 1.8918597e+00 -5.7378563e-01 166 | 1.6794794e+00 2.1059227e+00 9.1312791e-01 167 | 4.6112895e-04 -2.9775576e+00 -1.2874568e-02 168 | -2.5174799e+00 2.1861624e-01 1.0240149e+00 169 | 1.2027535e+00 -2.0491825e+00 1.0092630e+00 170 | -2.7440642e+00 1.2750476e+00 3.0383901e-01 171 | -7.8414543e-01 1.8826500e+00 -1.0785807e+00 172 | 1.2859315e+00 -1.7594455e+00 9.7628636e-01 173 | 1.0429415e+00 1.9852730e+00 1.0099059e+00 174 | 8.8575124e-01 5.5251466e-01 -3.7037807e-02 175 | 2.3050661e+00 -9.1654197e-02 -1.0637938e+00 176 | 1.3085527e+00 -6.6432221e-01 7.2505088e-01 177 | 9.9840908e-01 3.4233294e-01 1.3828527e-01 178 | -5.6879022e-01 1.8270069e+00 -9.1357539e-01 179 | -2.5616437e+00 5.5653724e-01 9.0281404e-01 180 | -4.4514962e-01 -9.6254603e-01 2.8389622e-01 181 | -------------------------------------------------------------------------------- /datasets/crater_tuto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuCarriere/tda-tutorials/706e95037ebc3370b6cf67515896ab6b01120701/datasets/crater_tuto -------------------------------------------------------------------------------- /datasets/data_acc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuCarriere/tda-tutorials/706e95037ebc3370b6cf67515896ab6b01120701/datasets/data_acc -------------------------------------------------------------------------------- /datasets/tore3D_1307.off: -------------------------------------------------------------------------------- 1 | OFF 2 | 1307 0 0 3 | -1.081352 -0.451815 0.237511 4 | -1.062873 -0.492063 -0.246058 5 | -0.490280 -0.890039 0.299674 6 | -1.094597 -0.620156 0.153419 7 | -0.517128 -1.189962 -0.039580 8 | 1.152877 0.300175 -0.231559 9 | 0.502337 1.174528 0.114471 10 | -0.299269 -1.235308 -0.128350 11 | 0.559591 1.172809 -0.019004 12 | 0.184193 -0.676264 -0.024016 13 | -0.888412 0.748820 -0.252659 14 | -0.859062 -0.581840 0.297612 15 | 0.293395 -1.216582 -0.163670 16 | 0.393949 -1.126922 -0.228892 17 | 0.441284 -1.075139 -0.252409 18 | -0.658443 0.286084 0.102036 19 | -0.770782 -0.787327 -0.282279 20 | -0.406644 1.191333 -0.151820 21 | 0.421148 0.751386 0.266188 22 | -0.337991 -1.233999 0.109125 23 | -0.576506 0.405645 -0.054051 24 | 0.359474 0.613240 0.079974 25 | -0.455484 -0.568690 -0.127880 26 | 0.702136 -0.235409 -0.150928 27 | 0.091056 -0.696011 0.037399 28 | -0.064213 -1.043207 -0.296606 29 | -0.066480 -0.708601 -0.083866 30 | -0.866010 -0.584473 -0.296793 31 | 0.476020 0.521113 0.058829 32 | 0.470937 0.518518 -0.020041 33 | 0.436955 0.578033 0.118941 34 | 0.510216 0.479447 0.010043 35 | 0.552069 0.434267 -0.037525 36 | 0.570514 0.483559 0.162698 37 | 0.520778 0.488742 0.091457 38 | 0.007764 -1.064538 0.292870 39 | -0.050586 -1.121647 0.273674 40 | 0.055839 -1.248122 0.166563 41 | -0.032797 -1.208186 0.215517 42 | -0.111026 -1.277187 0.102083 43 | -0.108199 -1.228175 0.189078 44 | -0.130166 -1.089441 0.283875 45 | -0.152281 -0.988000 0.299890 46 | -0.257364 -1.167207 0.227592 47 | -0.171612 -1.165220 0.241502 48 | -1.162998 0.381345 -0.199780 49 | -1.118806 0.446593 -0.219113 50 | -0.969520 0.369639 -0.297369 51 | -1.015149 0.442441 -0.279944 52 | -0.945706 0.502039 -0.291395 53 | -0.907852 0.668109 -0.271495 54 | -0.989109 0.583976 -0.260348 55 | -1.151615 0.505514 -0.153644 56 | -1.207510 0.471993 -0.044521 57 | -1.104315 0.650680 -0.102654 58 | -1.092710 0.584417 -0.180772 59 | -0.520165 0.523045 0.145339 60 | -0.908993 0.242970 0.293971 61 | -0.810558 0.265720 0.261300 62 | -0.897194 0.450947 0.299838 63 | -0.801677 0.368615 0.275680 64 | -0.618631 0.339910 -0.058175 65 | -0.745800 0.194272 0.193649 66 | -0.764778 0.089444 0.192796 67 | -0.677218 0.179465 -0.017122 68 | -0.951381 0.107469 -0.296882 69 | -1.044006 0.122763 -0.295486 70 | -1.130206 0.327437 -0.242377 71 | -1.039272 0.319024 -0.286828 72 | -1.006740 0.250370 -0.297517 73 | -1.074288 0.196042 -0.285418 74 | -1.179201 0.271080 -0.214486 75 | -1.159801 0.205309 -0.241580 76 | -1.262356 0.149537 -0.128957 77 | -1.209803 0.141532 -0.206239 78 | -1.103598 0.056448 -0.281019 79 | -1.069017 -0.026030 -0.291850 80 | -1.230492 -0.003439 -0.192273 81 | -1.186921 0.066026 -0.233374 82 | -1.239215 0.383964 -0.040221 83 | -1.221544 0.353027 -0.127998 84 | -1.231122 0.282629 -0.144722 85 | -1.265581 0.224586 -0.093610 86 | -1.278661 0.235723 -0.002121 87 | -1.258566 0.316739 0.036060 88 | -1.142814 0.618337 0.016377 89 | -1.186973 0.519848 0.048538 90 | -1.002081 0.324515 0.294944 91 | -0.998092 0.428671 0.287072 92 | -1.081725 0.504658 0.228721 93 | -1.161877 0.464839 0.162892 94 | -1.228669 0.307236 0.137309 95 | -1.223687 0.221595 0.175255 96 | -1.094190 0.299505 0.267834 97 | -1.172804 0.362343 0.194898 98 | -1.287785 0.080944 -0.076717 99 | -1.278902 0.004250 -0.110779 100 | -1.296965 0.086769 0.015989 101 | -1.290442 0.014796 0.076047 102 | -1.257240 0.161846 0.135908 103 | -1.285433 0.163110 0.051651 104 | -0.886853 0.152690 -0.282767 105 | -0.904457 0.223940 -0.291991 106 | -0.853657 0.340015 -0.288701 107 | -0.662561 0.323217 -0.144815 108 | -0.688153 0.235729 -0.124945 109 | -0.746102 0.209917 -0.198615 110 | -0.825513 0.260841 -0.268220 111 | -0.814460 0.106161 -0.241124 112 | -0.751881 0.125125 -0.182955 113 | -0.694463 0.087754 -0.002227 114 | -0.718096 0.030274 0.104055 115 | -0.725588 -0.037936 -0.124016 116 | -0.715162 0.057103 -0.100962 117 | -0.589244 0.833226 -0.299481 118 | -0.698686 0.797210 -0.293987 119 | -0.724145 0.963727 -0.218762 120 | -0.772661 0.863564 -0.254443 121 | -0.952389 0.746095 -0.214405 122 | -1.037783 0.734366 -0.127409 123 | -0.906947 0.888998 -0.130794 124 | -0.879694 0.826349 -0.216987 125 | -0.708976 0.691352 -0.299681 126 | -0.795825 0.632666 -0.299354 127 | -1.094557 0.205733 0.277474 128 | -1.166956 0.180982 0.239452 129 | -1.235100 0.093251 0.182145 130 | -1.252852 0.020112 0.161546 131 | -1.122616 0.045423 0.273322 132 | -1.176019 0.104304 0.239683 133 | -0.831534 0.028847 -0.248610 134 | -0.784800 -0.051320 -0.210683 135 | -0.970175 -0.039735 -0.298404 136 | -0.915801 0.031759 -0.287960 137 | -1.017315 0.133847 0.298781 138 | -1.040809 0.053958 0.296991 139 | -0.850253 0.061846 0.261250 140 | -0.922621 0.144598 0.292551 141 | -1.205576 -0.083392 -0.215756 142 | -1.127676 -0.097664 -0.269488 143 | -1.218875 -0.228370 -0.179640 144 | -1.241479 -0.151333 -0.164511 145 | -1.281008 -0.141697 -0.081100 146 | -1.282725 -0.207501 -0.019002 147 | -1.295404 -0.061623 0.045226 148 | -1.294057 -0.065990 -0.051164 149 | -1.266583 -0.280977 -0.040054 150 | -1.240056 -0.292948 -0.121946 151 | -1.272968 -0.133906 0.108272 152 | -1.274739 -0.205619 0.072097 153 | -1.254749 -0.331515 0.036391 154 | -1.230958 -0.414312 0.026169 155 | -1.188467 -0.290913 0.199876 156 | -1.247215 -0.280317 0.111825 157 | -0.714306 -0.076055 0.102946 158 | -0.722893 -0.247937 0.185450 159 | -0.755066 -0.146639 0.191478 160 | -0.892565 -0.032108 0.280205 161 | -0.993747 -0.023773 0.299917 162 | -0.848739 -0.126278 0.264223 163 | -1.137674 -0.030533 0.266157 164 | -1.209182 -0.047928 0.214183 165 | -1.221441 -0.129173 0.194550 166 | -1.160987 -0.202671 0.240867 167 | -1.069850 -0.172552 0.288004 168 | -1.063790 -0.080596 0.292372 169 | -1.158039 -0.249717 -0.236406 170 | -1.100040 -0.186683 -0.276695 171 | -1.150286 -0.337789 -0.224600 172 | -1.074319 -0.379918 -0.265438 173 | -1.211559 -0.436746 -0.083952 174 | -1.207229 -0.363808 -0.148360 175 | -0.931978 -0.130288 -0.293972 176 | -0.829416 -0.140227 -0.254308 177 | -0.987281 -0.311755 -0.297765 178 | -1.005930 -0.209775 -0.298601 179 | -0.521727 0.765192 -0.290775 180 | -1.148019 -0.386210 0.212818 181 | -1.190078 -0.459193 0.118044 182 | -1.158436 -0.559820 0.087646 183 | -1.167821 -0.516767 -0.114878 184 | -1.096278 -0.674600 -0.086267 185 | -1.155066 -0.591214 -0.036592 186 | -0.771608 1.005459 -0.135935 187 | -0.852825 0.959308 -0.097955 188 | -0.814246 1.007568 0.052984 189 | -0.869887 0.966193 -0.005886 190 | -0.965682 0.863491 -0.052417 191 | -1.028122 0.791500 -0.038978 192 | -0.927269 0.875414 0.119585 193 | -0.930881 0.906369 0.024163 194 | -0.566961 0.990224 0.264677 195 | -0.534303 1.091724 0.208631 196 | -0.718230 1.074222 -0.067833 197 | -0.745807 1.063247 0.028303 198 | -0.691291 1.076225 0.109998 199 | -0.602869 1.125480 0.115647 200 | -0.618246 1.129229 -0.085232 201 | -0.561684 1.171822 0.013519 202 | -0.450125 1.218907 0.016890 203 | -0.427083 1.134526 0.212045 204 | -0.271294 1.244331 0.122793 205 | -0.387285 1.213311 0.122658 206 | -1.094776 0.667045 0.101590 207 | -1.058368 0.607909 0.203007 208 | -0.978607 0.795203 0.147752 209 | -1.045755 0.757303 0.071993 210 | -0.801245 0.978278 0.141861 211 | -0.848741 0.906595 0.177594 212 | -0.668853 0.960921 0.246697 213 | -0.722169 1.011591 0.176481 214 | -0.480102 0.515515 0.050987 215 | -0.713545 -0.254054 -0.176596 216 | -0.686648 -0.346332 -0.191457 217 | -0.878900 -0.326981 -0.293245 218 | -0.797228 -0.236768 -0.248167 219 | -0.935677 0.734226 0.232423 220 | -0.967497 0.636933 0.254631 221 | -0.888477 0.555640 0.296089 222 | -0.791078 0.572816 0.298952 223 | -0.705808 0.865927 0.276371 224 | -0.802219 0.847107 0.249569 225 | -0.839916 0.754886 0.270695 226 | -0.771240 0.672138 0.299109 227 | -0.613878 0.599194 0.264134 228 | -0.530763 0.595344 0.221167 229 | -0.640168 0.780483 0.299749 230 | -0.673841 0.682444 0.297213 231 | -1.049085 -0.401913 0.273442 232 | -1.018454 -0.506904 0.266417 233 | -0.767742 -0.615905 0.299286 234 | -0.927725 -0.790117 0.205312 235 | -0.963772 -0.701033 0.230404 236 | -0.397985 0.701026 -0.229017 237 | -0.429407 0.774740 -0.277375 238 | -0.243658 0.752702 -0.215316 239 | -0.314726 0.693460 -0.182081 240 | -0.309573 0.643825 -0.091955 241 | -0.232485 0.661107 -0.021837 242 | -0.406312 0.572607 0.034624 243 | -0.391149 0.590737 -0.071491 244 | -0.551266 -0.809351 0.299338 245 | -0.687239 -0.975305 0.229314 246 | -0.536247 0.795816 0.297073 247 | -0.376939 0.918504 0.299808 248 | -0.494239 0.903007 0.298412 249 | -0.347646 0.634621 0.116610 250 | -0.251386 0.667185 0.087247 251 | -0.585533 -0.668753 0.278789 252 | -0.515444 -0.720691 0.277880 253 | -0.584628 -0.577694 0.241249 254 | -0.675393 -0.440771 0.228850 255 | -0.671482 -0.539889 0.265697 256 | -0.853291 -0.420036 -0.295950 257 | -0.751319 -0.421284 -0.266151 258 | -0.730875 -0.506183 -0.278896 259 | -0.790705 -0.568691 -0.299425 260 | -1.040254 -0.658033 -0.191569 261 | -0.916951 -0.512416 -0.295830 262 | -0.810410 -0.638033 -0.298556 263 | -0.748693 -0.696571 -0.299261 264 | -0.953502 -0.699942 -0.237685 265 | -0.889123 -0.651913 -0.282308 266 | 0.962416 0.841972 -0.111265 267 | 0.913452 0.821515 -0.194271 268 | 0.810323 0.959205 -0.157265 269 | 0.825787 0.882616 -0.215781 270 | 0.654429 0.921109 -0.270355 271 | 0.740022 0.854310 -0.270155 272 | 0.617250 0.707515 -0.293668 273 | 0.729631 0.755312 -0.295664 274 | 0.929579 0.731572 -0.237493 275 | 1.025178 0.659435 -0.204964 276 | 0.815022 0.609543 -0.299435 277 | 0.829173 0.699676 -0.287674 278 | -0.954822 -0.852912 0.106773 279 | -0.920233 -0.786312 -0.213849 280 | -0.888107 -0.920442 -0.110019 281 | -0.950851 -0.845548 -0.125402 282 | -0.204577 1.197671 0.209135 283 | -0.047190 1.054470 0.294865 284 | -0.140538 0.995875 0.299919 285 | -0.183526 0.717846 0.151647 286 | -0.028992 0.841029 0.254906 287 | -0.131597 0.885679 0.281198 288 | -0.893964 -0.927064 0.084480 289 | -0.872584 -0.962902 -0.015965 290 | -0.757646 -1.003637 0.153780 291 | -0.825670 -0.941871 0.162142 292 | -0.562879 1.104166 -0.180672 293 | -0.545627 0.937180 -0.287941 294 | -0.612412 1.007909 -0.240620 295 | -0.617710 -0.377137 -0.116819 296 | -0.280120 -0.643123 0.027697 297 | -0.362574 -0.598874 0.004105 298 | -0.641128 -0.520733 -0.244197 299 | -0.583385 -0.459863 -0.154090 300 | -0.508969 -0.499792 -0.087955 301 | -0.217732 1.280782 0.020568 302 | -0.044103 1.290446 -0.071942 303 | -0.103040 1.295146 0.019918 304 | -0.092171 1.215808 0.204421 305 | -0.026018 1.151911 0.258433 306 | 0.071646 1.277176 0.109400 307 | -0.042088 1.275636 0.116383 308 | -0.428680 0.956160 -0.296166 309 | -0.365528 1.061240 -0.273915 310 | -0.271612 0.843132 -0.277322 311 | -0.375317 0.857960 -0.293228 312 | -0.200079 0.918983 -0.294116 313 | -0.178178 1.215719 -0.194119 314 | -0.075228 1.249002 -0.163810 315 | -0.051371 1.064720 -0.292426 316 | -0.749268 -1.055549 0.055744 317 | -0.800770 -1.021747 -0.030796 318 | -0.810673 -0.939807 -0.178594 319 | -0.676875 -1.042950 -0.174886 320 | -0.764002 -1.010285 -0.137011 321 | -0.607360 -0.978326 -0.258591 322 | -0.639279 -0.869686 -0.289246 323 | -0.099286 0.882593 -0.278219 324 | -0.026016 0.952109 -0.296002 325 | -0.075059 0.785864 -0.213491 326 | 0.022346 0.754006 -0.172106 327 | -0.147283 0.691698 -0.065795 328 | -0.152610 0.736776 -0.169325 329 | -0.378927 -1.218959 -0.116129 330 | -0.460774 -1.212046 -0.046903 331 | -0.673535 -1.110549 0.021351 332 | -0.641230 -1.110616 -0.100066 333 | -0.552196 -1.145175 -0.127541 334 | -0.478087 -1.206587 0.038229 335 | -0.426464 -1.201374 0.120116 336 | -0.602509 -1.137404 0.087065 337 | -0.542556 -1.180242 0.029905 338 | -0.562520 -1.097531 0.188483 339 | -0.460930 -1.132398 0.201171 340 | -0.595745 -1.009843 0.245200 341 | 0.018426 -0.699933 0.003927 342 | -0.220857 -0.669403 -0.053967 343 | -0.136855 -0.687966 -0.029266 344 | -0.039762 -0.737462 -0.147506 345 | 0.013375 -0.765153 -0.187063 346 | -0.161318 -0.763629 -0.204449 347 | -0.102092 -0.735829 -0.155003 348 | -0.501991 -1.011704 -0.270374 349 | -0.385708 -1.151435 -0.209805 350 | -0.481519 -1.109550 -0.214688 351 | -0.084473 -0.912505 0.287939 352 | -0.009384 -0.954155 0.296280 353 | -0.235834 -0.958771 0.299674 354 | -0.264772 -0.680387 0.130846 355 | -0.343569 -0.823271 0.280057 356 | -0.251071 -0.852290 0.278391 357 | -0.090018 -0.814576 0.239527 358 | -0.013113 -0.763248 0.184274 359 | -0.028831 -0.712816 0.088689 360 | -0.115013 -0.698739 0.069244 361 | -0.182891 -0.715992 0.147883 362 | -0.173557 -0.786385 0.228326 363 | -0.299909 -1.096421 -0.266587 364 | -0.140175 -1.059353 -0.292189 365 | -0.198818 -1.124595 -0.263882 366 | -0.182305 -1.281469 0.057550 367 | -0.312375 -1.255560 -0.061168 368 | -0.156831 -1.204198 -0.209697 369 | -0.040651 -1.198621 -0.224542 370 | -0.154841 -1.287160 -0.046290 371 | -0.219968 -1.256120 -0.119186 372 | -0.065222 0.696920 -0.002844 373 | 0.026516 0.706518 -0.064130 374 | -0.007319 0.755929 0.174347 375 | -0.083290 0.717101 0.112792 376 | 0.027699 1.128169 -0.270914 377 | 0.014769 1.214505 -0.209679 378 | 0.061354 1.289607 -0.072153 379 | 0.123107 1.293828 0.011937 380 | 0.194987 1.222109 -0.182960 381 | 0.095568 1.249916 -0.160038 382 | 0.005081 -1.109260 -0.279505 383 | -0.126805 -0.982559 -0.299961 384 | -0.185024 -0.908465 -0.290877 385 | -0.134344 -0.830990 -0.254870 386 | -0.030626 -0.832050 -0.249210 387 | 0.009648 -0.910269 -0.286484 388 | -0.050433 -0.969471 -0.298845 389 | 0.041177 1.007630 0.300057 390 | 0.054442 0.902242 0.284235 391 | 0.113508 1.077381 0.288041 392 | 0.208155 1.053604 0.290424 393 | 0.129841 1.227050 0.187522 394 | 0.075815 1.162148 0.250734 395 | 0.240147 1.215023 0.181620 396 | 0.279879 1.132062 0.249544 397 | 0.457600 1.159578 0.170861 398 | 0.382487 1.106421 0.246255 399 | 0.483023 0.975561 0.286352 400 | 0.398800 1.001107 0.289444 401 | 0.230786 0.939193 0.298007 402 | 0.153231 0.861608 0.272702 403 | 0.326097 0.914284 0.298337 404 | 0.300457 1.251699 0.085600 405 | 0.426068 1.218448 0.073121 406 | 0.274212 1.248636 -0.111198 407 | 0.236083 1.278119 -0.004401 408 | -0.058656 -1.291853 -0.064397 409 | 0.007691 -1.257719 -0.154006 410 | 0.059179 -1.292552 0.059443 411 | -0.033167 -1.297935 0.031239 412 | 0.524254 -1.172829 -0.093831 413 | 0.680024 -1.036405 -0.180477 414 | 0.588607 -1.019811 -0.241688 415 | 0.688092 -0.861809 -0.281993 416 | 0.588081 -0.921022 -0.285347 417 | 0.545699 -0.717525 -0.283527 418 | 0.104077 -1.060046 -0.293005 419 | 0.103169 -0.939224 -0.294890 420 | 0.190046 -0.865922 -0.277689 421 | 0.358496 -1.182321 -0.186063 422 | 0.195163 -1.103773 -0.274883 423 | 0.139164 -1.291090 -0.027577 424 | 0.114294 -1.259480 -0.141230 425 | 0.201509 -1.200514 -0.206958 426 | 0.365868 -1.225732 -0.110196 427 | 0.438981 -1.219682 -0.045834 428 | 0.240009 -1.277322 -0.010875 429 | 0.293495 -1.253573 -0.086921 430 | 0.275945 -0.973380 0.299654 431 | 0.057305 -0.799652 0.224755 432 | 0.052788 -0.894999 0.281478 433 | 0.122150 -0.936773 0.294861 434 | 0.128478 1.083846 -0.285647 435 | 0.211785 1.139038 -0.254607 436 | 0.308977 0.989490 -0.297975 437 | 0.307056 1.090644 -0.268967 438 | 0.381529 1.208847 -0.134663 439 | 0.472080 1.207292 -0.045157 440 | 0.487524 1.067336 -0.244599 441 | 0.395848 1.131245 -0.224775 442 | 0.384004 0.927480 -0.300089 443 | 0.476426 0.961494 -0.290944 444 | 0.554536 0.885807 -0.296415 445 | 0.528181 0.772403 -0.292877 446 | 0.099619 0.801283 -0.229813 447 | 0.072511 0.906825 -0.285850 448 | 0.145019 0.974900 -0.299572 449 | 0.234103 0.933480 -0.297689 450 | 0.356271 0.829250 -0.283622 451 | 0.423502 0.747092 -0.264788 452 | 0.202947 0.768384 -0.218615 453 | 0.262419 0.835079 -0.272805 454 | 0.288495 -1.255384 0.083645 455 | 0.402270 -1.228877 0.063658 456 | 0.232743 -1.215498 0.182993 457 | 0.284587 -1.141892 0.242286 458 | 0.235422 -1.056762 0.288326 459 | 0.148416 -1.038004 0.295980 460 | 0.093182 -1.108653 0.277987 461 | 0.127978 -1.204079 0.213226 462 | 0.247820 0.694114 -0.144552 463 | 0.279902 0.717162 0.192782 464 | 0.175906 0.762650 0.206597 465 | 0.096975 0.728765 0.141098 466 | 0.554793 1.119556 0.166533 467 | 0.557149 1.031838 0.245398 468 | 0.707704 0.981963 0.214120 469 | 0.621770 0.975174 0.255932 470 | 0.499888 0.883087 0.299571 471 | 0.633511 0.819251 0.297640 472 | 0.585835 0.888221 0.292755 473 | 0.382817 -1.129194 0.230101 474 | 0.450111 -1.177304 0.148434 475 | 0.554877 -1.062688 0.224601 476 | 0.547087 -1.134743 0.149614 477 | 0.616089 -1.141655 -0.038338 478 | 0.690686 -1.084182 -0.091947 479 | 0.713191 -1.060448 0.112490 480 | 0.626418 -1.127788 0.075791 481 | 0.622131 -1.005820 0.238017 482 | 0.704955 -1.003844 0.196622 483 | 0.372015 -0.868978 0.294789 484 | 0.353677 -0.965625 0.298543 485 | 0.409685 -1.040978 0.275379 486 | 0.488880 -1.017382 0.270835 487 | 0.592248 -0.930935 0.281773 488 | 0.636318 -0.857503 0.292346 489 | 0.454105 -0.849356 0.297671 490 | 0.509796 -0.931635 0.293481 491 | 0.100362 -0.733003 -0.149052 492 | 0.106011 -0.694022 -0.035885 493 | 0.186966 -0.762933 -0.209494 494 | 0.264656 -0.648763 -0.020676 495 | 0.171153 -0.682499 0.048323 496 | 0.644979 1.109511 0.098613 497 | 0.723575 1.042383 0.133371 498 | 0.643327 1.129261 -0.012966 499 | 0.731125 1.066529 -0.063191 500 | 0.735769 1.021555 -0.151593 501 | 0.661112 1.016580 -0.211551 502 | 0.577174 1.089469 -0.188525 503 | 0.569973 1.153206 -0.089037 504 | 0.496925 0.607536 0.209207 505 | 0.582530 0.553639 0.226988 506 | 0.600442 0.730008 0.294883 507 | 0.499216 0.692742 0.261996 508 | 0.497070 -0.760675 0.285834 509 | 0.595361 -0.774001 0.299140 510 | 0.462269 -0.669636 0.235124 511 | 0.543659 -0.590459 0.226011 512 | 0.366772 -0.666334 0.180901 513 | 0.462710 -0.543362 -0.089479 514 | 0.541941 -0.471227 -0.103146 515 | 0.518095 -0.634633 -0.239425 516 | 0.443382 -0.612238 -0.173940 517 | 0.770376 0.902477 0.234897 518 | 0.728863 0.828294 0.281473 519 | 0.682704 0.684132 0.298120 520 | 0.677508 0.589203 0.282142 521 | 0.867906 0.716179 0.272504 522 | 0.765689 0.743942 0.292183 523 | 0.791940 -1.024801 0.052917 524 | 0.774972 -1.039592 -0.044206 525 | 0.763018 -0.975194 -0.182386 526 | 0.773694 -0.897213 -0.236617 527 | 0.904634 -0.917168 -0.082862 528 | 0.822859 -0.981979 -0.104505 529 | 0.700611 -0.764893 -0.297920 530 | 0.632368 -0.707732 -0.295909 531 | 0.585191 -0.575751 -0.240822 532 | 0.595841 -0.488753 -0.193600 533 | 0.717391 -0.584984 -0.290581 534 | 0.647996 -0.619303 -0.281588 535 | 0.613023 0.606343 -0.266521 536 | 0.711991 0.567597 -0.286250 537 | 0.576003 0.461515 -0.146199 538 | 0.542279 0.550486 -0.195749 539 | 0.800811 1.023281 -0.019748 540 | 0.804401 1.009700 0.073645 541 | 0.920616 0.910473 -0.056411 542 | 0.852528 0.967320 -0.079500 543 | 0.646476 -0.611121 0.278777 544 | 0.665480 -0.711019 0.298794 545 | 0.726785 -0.852133 0.275179 546 | 0.769212 -0.921322 0.223643 547 | 0.854869 -0.722552 0.275257 548 | 0.754953 -0.761594 0.291154 549 | 0.929233 -0.848637 -0.152528 550 | 0.859708 -0.837695 -0.223687 551 | 0.784008 -0.718281 -0.293370 552 | 0.783025 -0.630882 -0.299905 553 | 0.926067 -0.692431 -0.256085 554 | 0.860366 -0.753068 -0.263737 555 | 0.863227 0.882869 0.186969 556 | 0.925960 0.787953 0.208249 557 | 0.939989 0.895718 0.032622 558 | 0.876337 0.936474 0.101820 559 | 0.872470 -0.946356 0.086184 560 | 0.939219 -0.897996 0.014703 561 | 0.921253 -0.791732 0.209547 562 | 0.861473 -0.893730 0.178149 563 | 1.011950 -0.754854 0.145024 564 | 1.015580 -0.807465 0.037848 565 | 0.742315 -0.551148 0.290009 566 | 0.858941 -0.609519 0.294990 567 | 0.934448 -0.430807 0.298546 568 | 0.954522 -0.543808 0.283316 569 | 1.154398 -0.594227 0.030710 570 | 1.146413 -0.433385 0.197503 571 | 1.161911 0.448906 0.172005 572 | 0.882196 0.608502 0.291139 573 | 0.774028 0.543762 0.294907 574 | 0.958682 0.438441 0.295091 575 | 0.976412 0.550518 0.274661 576 | 1.029955 0.785386 -0.052364 577 | 1.008879 0.815541 0.040295 578 | 1.014120 0.759855 0.136049 579 | 0.676848 -0.179346 -0.010685 580 | 0.690110 -0.190866 -0.097051 581 | 0.669004 -0.306090 -0.142069 582 | 0.724850 -0.173534 -0.158843 583 | 0.744120 -0.102561 -0.167415 584 | 0.808341 -0.257098 -0.258833 585 | 0.748255 -0.224531 -0.205765 586 | 0.742118 0.090151 -0.161946 587 | 0.676606 0.180382 0.011167 588 | 0.655121 -0.254165 0.040569 589 | 0.625228 -0.321331 -0.041687 590 | 0.573020 -0.403162 -0.021541 591 | 0.735876 -0.441472 0.264158 592 | 0.831858 -0.387813 0.288421 593 | 0.684045 -0.281952 0.149830 594 | 0.660509 -0.387710 0.187547 595 | 0.858557 0.392168 0.294688 596 | 0.768042 0.439061 0.277044 597 | 0.612020 0.413813 0.147531 598 | 0.591019 0.379264 0.035168 599 | 0.627978 0.309341 0.001827 600 | 0.662612 0.251153 0.072768 601 | 0.701323 0.280691 0.174432 602 | 0.687070 0.380323 0.210031 603 | 1.118092 -0.651290 -0.059560 604 | 1.055819 -0.750298 -0.053264 605 | 1.001667 -0.771773 -0.141811 606 | 0.995520 -0.699458 -0.207720 607 | 1.108977 -0.585948 -0.159087 608 | 1.038365 -0.615304 -0.217255 609 | 0.917814 -0.606493 -0.282803 610 | 0.845411 -0.577835 -0.299133 611 | 0.987525 -0.557775 -0.268346 612 | 0.889943 0.542554 -0.297015 613 | 1.222820 0.415983 0.069436 614 | 1.217593 0.305147 -0.156870 615 | 1.144438 -0.478794 -0.179068 616 | 1.208277 -0.427621 -0.102134 617 | 1.235958 -0.306822 -0.122413 618 | 1.215422 -0.406665 0.102329 619 | 1.206357 -0.483060 0.010549 620 | 1.185614 -0.245192 -0.213354 621 | 0.871611 -0.192130 -0.280159 622 | 0.818725 -0.097645 -0.243261 623 | 1.025984 -0.096418 -0.298406 624 | 0.980099 -0.197894 -0.299969 625 | 0.863848 -0.413479 -0.297150 626 | 0.817636 -0.496759 -0.296888 627 | 0.733302 -0.504268 -0.279179 628 | 0.674549 -0.446113 -0.231166 629 | 0.705405 -0.364418 -0.218107 630 | 0.799773 -0.342705 -0.270286 631 | 1.122262 0.352151 0.242808 632 | 1.021343 0.354050 0.288929 633 | 0.860115 0.286518 0.285114 634 | 0.777918 0.224508 0.231974 635 | 0.959504 0.261832 0.299707 636 | 0.762268 -0.219779 0.217501 637 | 0.839147 -0.280112 0.276984 638 | 1.001574 -0.341729 0.294266 639 | 1.105292 -0.335866 0.256625 640 | 0.980311 -0.132138 0.299837 641 | 0.940644 -0.246220 0.298701 642 | 1.165480 0.233322 -0.232930 643 | 0.656768 0.422261 -0.204497 644 | 0.726403 0.481505 -0.270911 645 | 0.832377 0.463625 -0.296040 646 | 0.863536 0.370322 -0.293756 647 | 0.962370 0.164539 -0.298955 648 | 1.016050 0.073361 -0.299309 649 | 0.963117 -0.010756 -0.297558 650 | 0.859511 -0.010374 -0.264817 651 | 0.814212 0.075072 -0.238101 652 | 0.858030 0.158883 -0.271600 653 | 1.115317 0.045633 -0.276695 654 | 1.185542 0.113619 -0.231393 655 | 1.195818 -0.124843 -0.221636 656 | 1.120924 -0.063365 -0.273934 657 | 0.782512 0.114529 0.215037 658 | 0.775154 -0.108192 0.206922 659 | 1.164754 0.237906 0.233001 660 | 1.094081 -0.111437 0.282761 661 | 1.154254 -0.216724 0.243831 662 | 1.233599 0.006519 0.188448 663 | 1.143764 0.000654 0.263208 664 | 1.265412 -0.086944 0.134226 665 | 1.236869 -0.198568 0.161288 666 | 1.256210 -0.286906 0.080777 667 | 1.275136 -0.241531 -0.032615 668 | 1.259630 -0.062482 -0.147524 669 | 1.256014 0.059308 -0.153941 670 | 1.296757 -0.052817 0.036629 671 | 1.290030 -0.119559 -0.050287 672 | 0.709465 -0.047610 -0.080018 673 | 0.693844 -0.095693 0.017962 674 | 0.723811 -0.052492 0.122263 675 | 0.725727 0.056212 0.127028 676 | 0.694529 0.095815 0.027164 677 | 0.708872 0.042114 -0.076576 678 | 1.270438 0.246598 -0.058191 679 | 1.259910 0.298051 0.055014 680 | 1.242345 0.212671 0.148578 681 | 1.266931 0.099039 0.129284 682 | 1.296990 0.060790 0.031381 683 | 1.287049 0.123373 -0.063715 684 | 0.789145 0.216251 -0.238613 685 | 0.728162 0.172093 -0.163104 686 | 0.682332 0.208230 -0.088440 687 | 0.656445 0.285993 -0.096871 688 | 0.687970 0.335464 -0.186786 689 | 0.780751 0.303558 -0.252109 690 | 0.135508 -0.782976 0.218312 691 | 0.169909 -0.866128 0.275945 692 | 0.243915 -0.884224 0.288209 693 | 0.302182 -0.818153 0.271380 694 | 0.287490 -0.731087 0.209549 695 | 0.192495 -0.720849 0.159476 696 | 0.370903 -1.033939 -0.283443 697 | 0.277237 -1.023820 -0.293778 698 | 0.273185 -0.916310 -0.296699 699 | -0.796540 -0.878001 0.235911 700 | -0.708436 -0.889039 0.267125 701 | -0.646483 -0.815647 0.297459 702 | -0.667236 -0.730681 0.299898 703 | -0.759885 -0.717053 0.296493 704 | -0.834289 -0.799007 0.256798 705 | -0.612888 0.534769 -0.234888 706 | -0.617458 0.636376 -0.277816 707 | -0.538548 0.680382 -0.269273 708 | -0.465081 0.646712 -0.220646 709 | -0.464578 0.578950 -0.153904 710 | -0.542161 0.512962 -0.160492 711 | -0.649026 0.356285 0.149854 712 | -0.592371 0.407559 0.104765 713 | -0.579940 0.472056 0.162251 714 | -0.635487 0.515446 0.238547 715 | -0.711330 0.492828 0.267841 716 | -0.714295 0.398239 0.237973 717 | -0.685261 0.484037 -0.253085 718 | -0.701891 0.392885 -0.227738 719 | -0.790928 0.394196 -0.276596 720 | -0.834396 0.477478 -0.297499 721 | -0.768501 0.533539 -0.293094 722 | -0.762294 -0.319516 0.245107 723 | -0.835549 -0.341110 0.284045 724 | -0.821897 -0.425285 0.290792 725 | -0.745804 -0.402675 0.258445 726 | 0.370568 -0.661759 -0.177739 727 | 0.350364 -0.725302 -0.228616 728 | 0.269312 -0.716197 -0.186586 729 | 0.296292 -0.662405 -0.121866 730 | -0.389697 -0.594860 -0.081527 731 | -0.394159 -0.631719 -0.157238 732 | -0.468058 -0.614941 -0.196464 733 | 1.054329 0.592118 0.215565 734 | 1.118434 0.550900 0.170789 735 | 1.119161 0.626165 0.101492 736 | 1.065042 0.672237 0.150358 737 | 1.202716 0.412027 -0.127709 738 | 1.155164 0.478490 -0.165348 739 | 1.212313 0.466093 -0.026041 740 | 1.057486 -0.660840 0.170278 741 | 1.114889 -0.610178 0.129444 742 | 1.103640 -0.536177 0.196273 743 | 1.038992 -0.580559 0.232303 744 | 0.302600 0.659550 0.122060 745 | 0.285892 0.642011 0.041481 746 | 0.346889 0.607680 -0.000538 747 | 0.413031 -0.929655 -0.299561 748 | 0.356975 -0.871187 -0.294306 749 | 0.397431 -0.787875 -0.276079 750 | 0.491573 -0.790195 -0.292010 751 | 0.503099 -0.880806 -0.299861 752 | -0.230347 1.037901 0.293338 753 | -0.252574 1.115751 0.263669 754 | -0.346938 1.086762 0.265383 755 | -0.325746 1.006858 0.294464 756 | -0.983754 -0.314178 0.298579 757 | -0.900572 -0.294456 0.295570 758 | -0.909603 -0.206607 0.292661 759 | -0.994319 -0.224547 0.299606 760 | -0.565330 0.413696 0.020050 761 | -0.547525 0.461399 -0.098082 762 | -0.527867 0.460442 -0.019763 763 | -0.280076 1.262025 -0.066755 764 | -0.261959 1.232560 -0.149640 765 | -0.386260 1.232627 -0.069757 766 | -0.259011 -1.259173 0.092090 767 | -0.281130 -1.219505 0.163988 768 | -0.312092 -1.260466 0.031755 769 | -0.583252 -0.403921 0.074423 770 | -0.608341 -0.345944 -0.011131 771 | -0.647202 -0.269335 0.026117 772 | -0.662918 -0.289520 0.116611 773 | -0.630989 -0.380907 0.144753 774 | 0.441252 0.822211 0.292631 775 | 0.361679 0.821086 0.282074 776 | 0.339515 0.749680 0.242679 777 | -0.310323 -1.101878 0.262833 778 | -0.301766 -1.024790 0.292255 779 | -0.383030 -1.016220 0.287557 780 | -0.392581 -1.088534 0.255606 781 | -1.010324 -0.812112 -0.047781 782 | -1.008865 -0.815856 0.039056 783 | -1.058848 -0.746022 0.054108 784 | -1.065420 -0.742579 -0.029529 785 | -0.395237 1.137124 -0.220310 786 | -0.471595 1.140205 -0.188323 787 | -0.338405 1.194313 -0.178527 788 | -0.699800 -0.109455 -0.070765 789 | -0.689467 -0.120599 0.010743 790 | -0.671033 -0.199956 -0.014290 791 | -0.688217 -0.191421 -0.092680 792 | 0.408102 0.663417 -0.203096 793 | 0.466253 0.585630 -0.163718 794 | 0.441485 0.557009 -0.079492 795 | 0.377190 0.599405 -0.069782 796 | 0.341626 0.653908 -0.145644 797 | -0.523619 -0.644705 -0.247708 798 | -0.511240 -0.750521 -0.285482 799 | -0.596144 -0.773469 -0.299212 800 | -0.656851 -0.683275 -0.295784 801 | -0.612259 -0.606882 -0.266568 802 | -0.473594 0.725633 0.268886 803 | -0.475706 0.654965 0.231692 804 | -0.393511 0.666313 0.197441 805 | -0.386707 0.728519 0.243539 806 | -0.226713 0.769971 0.226267 807 | -0.213057 0.836123 0.266821 808 | -0.309151 0.845991 0.283220 809 | -0.317285 0.776245 0.252873 810 | -0.213294 1.021565 -0.296975 811 | -0.267976 1.076045 -0.279727 812 | -0.196093 1.141235 -0.255162 813 | -0.146277 1.086413 -0.284270 814 | -0.839221 -0.808840 -0.250598 815 | -0.718594 -0.852266 -0.277379 816 | -0.786471 -0.873174 -0.243957 817 | 0.503781 -0.508397 0.096169 818 | 0.540943 -0.516324 0.162880 819 | 0.590295 -0.440457 0.143772 820 | 0.556546 -0.438798 0.070722 821 | 1.084562 0.281819 -0.274968 822 | 1.002617 0.250258 -0.298497 823 | 0.963113 0.338957 -0.299498 824 | 1.037546 0.369298 -0.282492 825 | -0.532627 -0.474451 0.087948 826 | -0.518299 -0.543742 0.167953 827 | -0.443480 -0.591791 0.149136 828 | -0.424565 -0.565344 0.064974 829 | -0.489497 -0.501100 0.020071 830 | -0.326613 -0.988326 -0.297219 831 | -0.423097 -0.944084 -0.297997 832 | -0.432796 -0.826832 -0.292235 833 | -0.345999 -0.809039 -0.274921 834 | -0.279305 -0.905123 -0.295123 835 | 0.515979 -1.070956 -0.233456 836 | 0.487322 -1.130354 -0.191475 837 | -0.925013 -0.626671 0.276302 838 | -0.865072 -0.495252 0.300282 839 | -0.935223 -0.536835 0.289813 840 | -0.694036 0.225684 0.130812 841 | -0.667444 0.225671 0.053514 842 | -0.638271 0.289192 0.023586 843 | -1.071978 -0.687841 0.123612 844 | -1.033204 -0.671857 0.189812 845 | -1.059406 -0.587136 0.213413 846 | -1.108029 -0.518786 -0.200463 847 | -1.005976 -0.519367 -0.269572 848 | -1.051147 -0.573816 -0.226187 849 | -0.256151 -0.689419 -0.141839 850 | -0.237598 -0.737223 -0.197979 851 | -0.317606 -0.741037 -0.229220 852 | -0.332805 -0.682788 -0.179335 853 | -0.434458 -0.956063 0.295992 854 | -0.418513 -0.880376 0.299329 855 | -0.520850 -0.950210 0.288273 856 | -0.406629 -0.654765 0.193769 857 | -0.435712 -0.703126 0.245543 858 | -0.365948 -0.743199 0.246380 859 | -0.335779 -0.691988 0.191801 860 | 0.845940 -0.044368 0.258445 861 | 0.920449 -0.047701 0.289810 862 | 0.924185 0.051448 0.290867 863 | 0.850188 0.054180 0.261087 864 | 1.002923 0.179360 0.299276 865 | 0.988118 0.102835 0.300023 866 | 1.085193 0.084243 0.286641 867 | 1.098530 0.165028 0.278701 868 | 1.096941 0.491263 -0.222004 869 | 1.047839 0.454144 -0.264349 870 | 0.986637 0.533674 -0.274259 871 | 1.038420 0.573741 -0.235162 872 | 0.345377 -0.609810 0.022919 873 | 0.373212 -0.611043 0.096142 874 | 0.439669 -0.553656 0.065038 875 | 0.418793 -0.561034 -0.005764 876 | 0.197046 0.678459 -0.061239 877 | 0.214682 0.666422 0.011519 878 | 0.131791 0.691916 0.050055 879 | 0.108886 0.692463 -0.025146 880 | 0.959843 -0.396427 -0.297619 881 | 1.020302 -0.294707 -0.293721 882 | 1.106118 -0.311297 -0.260537 883 | 1.092619 -0.419161 -0.247120 884 | 1.008918 -0.464677 -0.278913 885 | 1.149537 0.561453 -0.109365 886 | 1.091539 0.650928 -0.129086 887 | 1.087481 0.700464 -0.061449 888 | 1.136442 0.630776 0.011438 889 | 1.174761 0.553075 -0.030822 890 | 1.133565 0.623716 -0.062652 891 | 1.038339 -0.377038 -0.281436 892 | 0.162973 0.680410 -0.005997 893 | 0.392771 -0.583099 0.044769 894 | 1.046037 0.514975 -0.250228 895 | 1.042142 0.131698 0.296308 896 | 0.887198 0.005667 0.278026 897 | -0.385225 -0.697638 0.220953 898 | -0.287247 -0.712424 -0.190682 899 | -0.361292 -0.892823 -0.298239 900 | -0.480323 -0.532860 0.101348 901 | 1.021875 0.310137 -0.291827 902 | 0.547213 -0.474621 0.119170 903 | -0.208484 1.085819 -0.281035 904 | -0.265340 0.807132 0.259915 905 | -0.432875 0.692462 0.237538 906 | -0.579202 -0.687890 -0.282278 907 | 0.408028 0.608769 -0.136862 908 | -0.685228 -0.154704 -0.040935 909 | -1.038974 -0.782102 0.003329 910 | -0.345953 -1.058978 0.277886 911 | -0.622988 -0.336168 0.068561 912 | -0.333663 1.228897 -0.124423 913 | -0.946411 -0.259107 0.299701 914 | -0.288648 1.060153 0.283369 915 | 0.435763 -0.849970 -0.296752 916 | 1.080817 -0.600194 0.185898 917 | 1.187064 0.491222 -0.095295 918 | 1.092250 0.614291 0.162193 919 | 0.321060 -0.689488 -0.180002 920 | -0.790436 -0.372131 0.272004 921 | -0.750981 0.453802 -0.274045 922 | -0.641491 0.433991 0.198160 923 | -0.538569 0.594090 -0.225269 924 | -0.738466 -0.806338 0.284981 925 | 0.335689 -0.955376 -0.300047 926 | 0.219879 -0.794505 0.243485 927 | 0.714547 0.251899 -0.176459 928 | 1.284759 0.177475 0.041395 929 | 0.701976 -0.000094 0.025814 930 | 1.293667 0.001496 -0.060971 931 | 1.283623 -0.167662 0.057339 932 | 1.196388 -0.100567 0.222714 933 | 1.188741 0.115287 0.227322 934 | 0.781304 0.003527 0.205291 935 | 1.197613 -0.005335 -0.224563 936 | 0.910174 0.076370 -0.287542 937 | 0.754686 0.394175 -0.260221 938 | 1.080500 0.163865 -0.284556 939 | 1.049075 -0.230342 0.290757 940 | 0.863443 -0.156463 0.273149 941 | 0.886441 0.162727 0.283041 942 | 1.065795 0.255608 0.284282 943 | 0.765245 -0.425605 -0.272580 944 | 0.919351 -0.101886 -0.290301 945 | 1.097663 -0.188737 -0.276717 946 | 1.248133 -0.364149 -0.011244 947 | 1.170256 -0.364441 -0.197203 948 | 1.243852 0.364273 -0.044454 949 | 1.133731 0.378613 -0.226953 950 | 0.950037 0.445355 -0.295828 951 | 0.913630 -0.503915 -0.296384 952 | 1.066848 -0.520520 -0.234196 953 | 1.061512 -0.683630 -0.143390 954 | 0.640481 0.333956 0.111468 955 | 0.770423 0.333989 0.252824 956 | 0.745613 -0.331928 0.237063 957 | 0.616144 -0.353610 0.078030 958 | 0.697696 0.128961 -0.076097 959 | 0.656083 0.245281 -0.019514 960 | 0.782450 0.143255 -0.219342 961 | 0.783315 -0.174863 -0.224851 962 | 0.735358 -0.287864 -0.213594 963 | 0.663794 -0.246043 -0.068058 964 | 0.700057 -0.130073 -0.084843 965 | 1.078931 0.719457 0.042099 966 | 0.872559 0.497771 0.299897 967 | 1.064970 0.471428 0.248964 968 | 1.174830 0.533671 0.073146 969 | 1.165577 -0.517894 0.117455 970 | 1.046029 -0.459347 0.263552 971 | 0.843475 -0.495601 0.299050 972 | 1.087216 -0.700345 0.058688 973 | 0.947530 -0.855401 0.116531 974 | 0.946399 0.851423 0.121924 975 | 0.854614 -0.665396 -0.288293 976 | 0.933853 -0.771911 -0.211684 977 | 0.821348 -0.826783 0.249217 978 | 0.755945 -0.660166 0.299903 979 | 0.870917 0.964023 0.010052 980 | 0.630665 0.511276 -0.234018 981 | 0.656377 -0.532049 -0.256787 982 | 0.711577 -0.672076 -0.299239 983 | 0.847823 -0.914921 -0.168488 984 | 0.858428 -0.976098 -0.011968 985 | 0.778314 0.647835 0.299678 986 | 0.825945 0.814106 0.254337 987 | 0.520044 -0.550086 -0.175867 988 | 0.499485 -0.490291 0.002695 989 | 0.454858 -0.586310 0.153266 990 | 0.564152 -0.681757 0.276917 991 | 0.587484 0.639916 0.269631 992 | 0.659302 1.089643 -0.122970 993 | 0.729996 1.073118 0.036291 994 | 0.280777 -0.661310 0.102565 995 | 0.196742 -0.690763 -0.102394 996 | 0.545238 -0.849572 0.299153 997 | 0.430846 -0.945793 0.297467 998 | 0.678016 -0.933021 0.256883 999 | 0.706615 -1.090987 0.012267 1000 | 0.631560 -1.075420 0.170197 1001 | 0.474461 -1.102604 0.223018 1002 | 0.524459 0.792483 0.295663 1003 | 0.677042 0.903799 0.271064 1004 | 0.638259 1.051658 0.190681 1005 | 0.209779 0.689675 0.109820 1006 | 0.290751 0.642813 -0.056385 1007 | 0.186576 -1.136193 0.258473 1008 | 0.342557 -1.203144 0.163966 1009 | 0.317527 0.737031 -0.225710 1010 | 0.167898 0.865240 -0.275581 1011 | 0.452548 0.850725 -0.297566 1012 | 0.484132 1.156008 -0.161150 1013 | 0.395626 1.031177 -0.280414 1014 | 0.222405 1.037605 -0.292985 1015 | 0.106590 -0.851849 0.264438 1016 | 0.198043 -0.961127 0.299476 1017 | 0.309138 -0.900195 0.296481 1018 | 0.341555 -1.253686 -0.018260 1019 | 0.213467 -1.260160 -0.111836 1020 | 0.296387 -1.130088 -0.247429 1021 | 0.192045 -0.986292 -0.299564 1022 | 0.288130 -0.801942 -0.261039 1023 | 0.446086 -0.702796 -0.248639 1024 | 0.595047 -0.807409 -0.299158 1025 | 0.680988 -0.956747 -0.244088 1026 | 0.592480 -1.104059 -0.159214 1027 | 0.433448 -1.183813 -0.148564 1028 | 0.039850 -1.294161 -0.053755 1029 | 0.349873 1.251193 -0.025144 1030 | 0.263298 0.817737 0.264375 1031 | 0.415561 0.897538 0.299856 1032 | 0.477293 1.073650 0.243567 1033 | 0.351666 1.193906 0.172983 1034 | 0.176656 1.151739 0.250687 1035 | 0.134091 0.972600 0.299294 1036 | -0.087780 -0.904717 -0.286028 1037 | 0.020739 -1.006647 -0.299486 1038 | 0.166393 1.275452 -0.089359 1039 | 0.113207 1.179685 -0.236258 1040 | 0.025541 0.705468 0.058925 1041 | -0.103112 -1.258094 -0.143523 1042 | -0.243233 -1.276510 -0.006395 1043 | -0.220601 -1.012859 -0.297423 1044 | -0.096562 -1.128849 -0.269241 1045 | -0.097820 -0.741547 0.162203 1046 | -0.269248 -0.752295 0.222120 1047 | -0.335014 -0.930542 0.299118 1048 | -0.014468 -0.848928 0.259489 1049 | -0.399618 -1.054522 -0.271504 1050 | -0.075808 -0.774613 -0.202316 1051 | -0.166639 -0.709791 -0.127486 1052 | -0.064692 -0.696862 0.003664 1053 | 0.022457 -0.717398 -0.100987 1054 | -0.483929 -1.037551 0.262555 1055 | -0.516662 -1.164995 0.118062 1056 | -0.596990 -1.153686 -0.024490 1057 | -0.466923 -1.177271 -0.135536 1058 | -0.392522 -1.238452 0.011467 1059 | -0.062508 0.720967 -0.116611 1060 | 0.000283 0.841427 -0.254475 1061 | -0.527635 -0.881717 -0.298495 1062 | -0.715712 -0.946184 -0.233992 1063 | -0.725448 -1.071146 -0.062676 1064 | -0.085621 1.167435 -0.246122 1065 | -0.124362 0.990962 -0.299777 1066 | -0.306633 0.961511 -0.298678 1067 | 0.019507 1.228251 0.194642 1068 | 0.010721 1.299333 0.020677 1069 | -0.164692 1.274488 -0.090192 1070 | -0.542117 -0.550397 -0.195481 1071 | -0.354184 -0.629887 0.113838 1072 | -0.314622 -0.639677 -0.086426 1073 | -0.418548 -0.705238 -0.239834 1074 | -0.555494 -0.429030 -0.027770 1075 | -0.485255 1.054094 -0.252320 1076 | -0.824014 -0.994260 0.072133 1077 | -0.120315 0.783749 0.216169 1078 | -0.043365 0.945925 0.294151 1079 | -0.140639 1.115889 0.272260 1080 | -0.868483 -0.866283 -0.195326 1081 | -0.949294 -0.887371 -0.012285 1082 | 0.934768 0.629323 -0.271342 1083 | 0.716838 0.657872 -0.297925 1084 | 0.637481 0.815215 -0.298063 1085 | 0.741681 0.945776 -0.220741 1086 | 0.886355 0.900773 -0.141404 1087 | 1.011776 0.749745 -0.150310 1088 | -0.849358 -0.722809 -0.276476 1089 | -0.963078 -0.604729 -0.266292 1090 | -0.820903 -0.503451 -0.296998 1091 | -0.715608 -0.600052 -0.291700 1092 | -0.591372 -0.476112 0.178584 1093 | -0.496234 -0.631264 0.225554 1094 | -0.295122 0.706965 0.187750 1095 | -0.417277 0.810449 0.286567 1096 | -0.758337 -0.941245 0.215972 1097 | -0.606537 -0.905749 0.285800 1098 | -0.592261 -0.747008 0.295486 1099 | -0.319623 0.622724 0.011634 1100 | -0.336120 0.766622 -0.251861 1101 | -0.230614 0.690614 -0.126746 1102 | -1.011110 -0.762588 0.137434 1103 | -0.866564 -0.696891 0.277708 1104 | -0.768817 -0.504952 0.288830 1105 | -0.926781 -0.414174 0.298443 1106 | -0.566321 0.687500 0.279264 1107 | -0.740593 0.769341 0.291323 1108 | -0.869486 0.657424 0.286230 1109 | -0.773690 -0.332442 -0.254055 1110 | -0.654199 -0.281884 -0.082753 1111 | -0.477093 0.522429 -0.063321 1112 | -0.761076 0.932961 0.219033 1113 | -1.023409 0.705858 0.176122 1114 | -0.316669 1.171607 0.208738 1115 | -0.333856 1.255383 0.022199 1116 | -0.498825 1.182537 -0.097484 1117 | -0.662063 1.118218 0.018235 1118 | -0.634137 1.050324 0.194884 1119 | -0.444113 1.021245 0.276952 1120 | -0.989021 0.836556 0.046266 1121 | -0.871789 0.945475 0.088068 1122 | -0.800765 1.019591 -0.041067 1123 | -1.111179 -0.593964 -0.148119 1124 | -1.113799 -0.663495 0.041517 1125 | -1.113335 -0.501697 0.201047 1126 | -0.470258 0.711833 -0.261737 1127 | -0.901328 -0.227061 -0.291633 1128 | -1.150844 -0.434771 -0.191904 1129 | -1.082069 -0.281890 -0.275609 1130 | -1.146876 -0.112645 0.258782 1131 | -0.965621 -0.122543 0.298437 1132 | -0.815534 -0.235538 0.258090 1133 | -0.688630 -0.187247 0.089101 1134 | -1.218876 -0.364691 0.125998 1135 | -1.234556 -0.209229 0.162613 1136 | -1.243078 -0.358125 -0.056401 1137 | -1.291799 -0.135678 0.012645 1138 | -1.179781 -0.165963 -0.231119 1139 | -1.262744 -0.217687 -0.104573 1140 | -0.948766 0.054904 0.296129 1141 | -0.871901 -0.050292 -0.272258 1142 | -1.193823 0.030164 0.228481 1143 | -1.103530 0.121596 0.278886 1144 | -0.695327 0.585352 -0.285173 1145 | -0.969277 0.814429 -0.138299 1146 | -0.823344 0.923277 -0.183927 1147 | -0.660499 0.902212 -0.274850 1148 | -0.614177 0.735157 -0.296825 1149 | -0.700365 -0.021777 -0.009941 1150 | -0.763507 0.038492 -0.185001 1151 | -0.744164 0.304834 -0.225524 1152 | -0.815437 0.181977 -0.250976 1153 | -1.277097 0.090381 0.105103 1154 | -1.298741 0.010112 -0.018292 1155 | -1.170109 0.266349 0.223723 1156 | -1.093022 0.400462 0.251565 1157 | -1.134482 0.568923 0.133131 1158 | -1.257375 0.301626 -0.061501 1159 | -1.263764 0.237232 0.091195 1160 | -1.157995 -0.013609 -0.253936 1161 | -1.249421 0.073709 -0.162266 1162 | -1.224630 0.213093 -0.174756 1163 | -1.102260 0.263601 -0.269010 1164 | -0.978337 0.179315 -0.300004 1165 | -1.009465 0.043444 -0.300077 1166 | -0.702293 0.143041 0.097832 1167 | -0.652204 0.262211 -0.041095 1168 | -0.799087 0.471327 0.290908 1169 | -0.901325 0.345953 0.298035 1170 | -0.827719 0.162785 0.255674 1171 | -0.573771 0.537543 0.210402 1172 | -0.608195 0.352016 0.040296 1173 | -0.539532 0.459420 0.071839 1174 | -1.161672 0.562918 -0.071742 1175 | -1.022200 0.663911 -0.205014 1176 | -0.873140 0.565987 -0.297309 1177 | -0.899071 0.420435 -0.299924 1178 | -1.077667 0.384472 -0.263383 1179 | -1.194517 0.427458 -0.132809 1180 | -0.221954 -1.074123 0.283686 1181 | -0.197812 -1.236929 0.161346 1182 | -0.027199 -1.269649 0.131024 1183 | 0.033153 -1.167080 0.248574 1184 | -0.071734 -1.020248 0.299181 1185 | 0.553785 0.441919 0.070900 1186 | 0.509938 0.535755 0.148952 1187 | 0.415637 0.563573 0.011890 1188 | 0.504684 0.506203 -0.092321 1189 | -0.100478 -1.165557 0.247145 1190 | -1.059598 0.514116 -0.241154 1191 | -0.716764 0.297246 0.199604 1192 | -1.134249 0.133226 -0.264320 1193 | -1.223679 0.409124 0.075771 1194 | -1.286767 0.157405 -0.040141 1195 | -0.931157 0.296156 -0.299125 1196 | -0.703442 0.148197 -0.105304 1197 | -1.190109 0.324692 -0.187302 1198 | -0.816138 0.749402 -0.280168 1199 | -1.215038 0.153564 0.197816 1200 | -0.876619 0.088736 -0.275358 1201 | -1.006467 0.225050 0.298517 1202 | -1.262985 -0.073425 -0.140711 1203 | -1.271486 -0.262955 0.033891 1204 | -0.783521 -0.029131 0.207660 1205 | -1.071746 -0.007821 0.291655 1206 | -1.199206 -0.295942 -0.186709 1207 | -1.264506 -0.056967 0.136794 1208 | -1.034512 -0.114702 -0.297369 1209 | -1.199315 -0.501852 0.000603 1210 | -0.911068 0.920378 -0.055649 1211 | -0.499617 1.172257 0.120120 1212 | -1.088676 0.709305 -0.014877 1213 | -0.758306 1.032974 0.104410 1214 | -0.614517 0.425404 -0.161404 1215 | -0.739086 -0.145185 -0.170103 1216 | -0.699324 0.587635 0.287443 1217 | -0.987609 0.533904 0.273485 1218 | -0.993118 -0.606965 0.251690 1219 | -1.087055 -0.285907 0.272603 1220 | -0.388057 0.637913 -0.159614 1221 | -0.604151 0.883993 0.291897 1222 | -0.446252 0.589326 0.147701 1223 | -0.671295 -0.638783 0.291060 1224 | 0.832245 0.794109 -0.260058 1225 | -1.016082 -0.753739 -0.139099 1226 | -0.894835 0.824646 0.207504 1227 | -0.247091 0.930871 0.297818 1228 | -0.880746 -0.870640 0.179956 1229 | -0.672892 1.055080 -0.163345 1230 | -0.692494 -0.344178 0.196723 1231 | -0.437475 -0.548657 -0.031920 1232 | -0.972922 -0.422594 -0.293486 1233 | -0.156200 1.264978 0.120963 1234 | -0.481776 0.854096 -0.299669 1235 | -0.288375 1.159083 -0.228295 1236 | -0.831926 -0.977799 -0.098569 1237 | -0.685803 -0.773099 -0.298065 1238 | -0.172297 0.816041 -0.249909 1239 | -0.662959 -0.434336 -0.216522 1240 | -0.669757 -1.066680 0.150107 1241 | -0.580343 -1.074976 -0.202341 1242 | -0.164271 -0.881216 0.281444 1243 | -0.280485 -1.197167 -0.193463 1244 | -0.157734 0.686583 0.046142 1245 | 0.010477 1.266321 -0.139080 1246 | -0.197007 -0.676013 0.049491 1247 | 0.031927 1.093881 0.285191 1248 | -0.241454 -0.811989 -0.258068 1249 | 0.305172 1.026459 0.291551 1250 | 0.185417 1.269667 0.099601 1251 | -0.109657 -1.295002 0.016156 1252 | -0.354647 -1.170912 0.199913 1253 | 0.482117 -0.991245 -0.281734 1254 | 0.296864 1.182822 -0.204655 1255 | 0.308390 0.901747 -0.296522 1256 | 0.164858 -1.271650 0.100107 1257 | 0.129654 0.719653 -0.133167 1258 | 0.550309 0.952475 0.283317 1259 | 0.522361 -1.187875 0.038151 1260 | 0.554652 -0.992806 0.267233 1261 | 0.066576 -1.001324 0.299941 1262 | 0.084642 -0.823150 -0.243917 1263 | 0.078487 -0.720663 0.119464 1264 | 0.546613 1.173373 0.054810 1265 | 0.048774 1.020560 -0.299526 1266 | 0.572081 0.994658 -0.261348 1267 | 0.086106 -1.178953 -0.236369 1268 | 0.389068 0.664193 0.190664 1269 | 0.324206 -1.056296 0.281174 1270 | 0.387759 -0.759751 0.261106 1271 | 0.368951 -0.608104 -0.081707 1272 | 0.682709 0.762105 0.299490 1273 | 0.750020 -1.029661 -0.123713 1274 | 0.585383 -0.652051 -0.272713 1275 | 0.507029 0.656832 -0.246647 1276 | 0.790019 1.012750 -0.096791 1277 | 0.676726 -0.791754 0.297507 1278 | 0.780244 -0.808226 -0.272429 1279 | 0.072286 0.802450 0.228718 1280 | -0.445675 -0.791086 0.284580 1281 | 0.794911 0.966254 0.162237 1282 | 0.791395 -0.982968 0.146609 1283 | 0.966902 -0.670928 0.241519 1284 | 0.979615 0.675052 0.231564 1285 | 0.630714 -0.501266 0.228137 1286 | 0.664544 0.483615 0.240031 1287 | 0.975127 -0.635308 -0.251803 1288 | 1.103024 0.571856 -0.176418 1289 | 1.168994 -0.543437 -0.080376 1290 | 0.907130 -0.302976 -0.296636 1291 | 0.931345 0.345940 0.300500 1292 | 0.909958 -0.338604 0.298790 1293 | 0.889916 0.259396 -0.290507 1294 | 0.611543 0.370879 -0.094045 1295 | 0.619942 -0.394671 -0.138017 1296 | 0.978067 0.854318 -0.032130 1297 | 0.983555 -0.839775 -0.064698 1298 | 1.050455 -0.009957 -0.296278 1299 | 1.019182 -0.004924 0.298903 1300 | 1.252915 -0.184549 -0.138450 1301 | 0.778990 -0.558492 -0.297438 1302 | 0.761885 -0.007291 -0.182637 1303 | 0.795919 0.534301 -0.297579 1304 | 1.242510 0.182706 -0.157288 1305 | 1.196213 -0.316951 0.183497 1306 | 0.703267 -0.168386 0.112542 1307 | 0.710297 0.170562 0.129136 1308 | 1.207701 0.332450 0.162218 1309 | 1.279836 0.005212 0.106332 1310 | -------------------------------------------------------------------------------- /datasets/trefoil_dist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuCarriere/tda-tutorials/706e95037ebc3370b6cf67515896ab6b01120701/datasets/trefoil_dist -------------------------------------------------------------------------------- /persistence_statistics.py: -------------------------------------------------------------------------------- 1 | def hausd_interval(data, level = 0.95, m=-1, B =1000,pairwise_dist = False, 2 | leaf_size = 2,ncores = None): 3 | 4 | ''' 5 | Subsampling Confidence Interval for the Hausdorff Distance between a 6 | Manifold and a Sample 7 | Fasy et al AOS 2014 8 | 9 | Input: 10 | data : a nxd numpy array representing n points in R^d, or a nxn matrix of pairwise distances 11 | m : size of each subsample. If m=-1 then m = n / np.log(n) 12 | B : number of subsamples 13 | level : confidence level 14 | pairwise_dist : if pairwise_dist = True then data is a nxn matrix of pairwise distances 15 | leaf_size : leaf size for KDTree 16 | ncores : number of cores for multiprocessing (if None then the maximum number of cores is used) 17 | 18 | Output: 19 | quantile for the Hausdorff distance 20 | 21 | 22 | ''' 23 | 24 | 25 | import numpy as np 26 | from multiprocessing import Pool 27 | from sklearn.neighbors import KDTree 28 | 29 | 30 | 31 | # sample size 32 | n = np.size(data,0) 33 | 34 | # subsample size 35 | if m == -1: 36 | m = int (n / np.log(n)) 37 | 38 | 39 | # Data is an array 40 | if pairwise_dist == False: 41 | 42 | # for subsampling 43 | # a reprendre sans shuffle slit 44 | 45 | 46 | global hauss_dist 47 | def hauss_dist(m): 48 | ''' 49 | Distances between the points of data and a random subsample of data of size m 50 | ''' 51 | I = np.random.choice(n,m) 52 | Icomp = [item for item in np.arange(n) if item not in I] 53 | tree = KDTree(data[I,],leaf_size=leaf_size) 54 | dist, ind = tree.query(data[Icomp,],k=1) 55 | hdist = max(dist) 56 | return(hdist) 57 | 58 | # parrallel computing 59 | with Pool(ncores) as p: 60 | dist_vec = p.map(hauss_dist,[m]*B) 61 | p.close() 62 | dist_vec = [a[0] for a in dist_vec] 63 | 64 | 65 | # Data is a matrix of pairwise distances 66 | else: 67 | def hauss_dist(m): 68 | ''' 69 | Distances between the points of data and a random subsample of data of size m 70 | ''' 71 | I = np.random.choice(n,m) 72 | hdist= np.max([np.min(data[I,j]) for j in np.arange(n) if j not in I]) 73 | return(hdist) 74 | 75 | # parrallel computing 76 | with Pool(ncores) as p: 77 | dist_vec = p.map(hauss_dist, [m]*B) 78 | p.close() 79 | 80 | 81 | # quantile and confidence band 82 | myquantile = np.quantile(dist_vec, level) 83 | c = 2 * myquantile 84 | 85 | return(c) 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | def truncated_simplex_tree(st,int_trunc=100): 94 | ''' 95 | This function return a truncated simplex tree 96 | 97 | Input: 98 | st : a simplex tree 99 | int_trunc : number of persistent interval keept per dimension (the largest) 100 | 101 | Ouptut: 102 | st_trunc_pers : truncated simplex tree 103 | ''' 104 | 105 | st.persistence() 106 | dim = st.dimension() 107 | st_trunc_pers = []; 108 | for d in range(dim): 109 | pers_d = st.persistence_intervals_in_dimension(d) 110 | d_l= len(pers_d) 111 | if d_l > int_trunc: 112 | pers_d_trunc = [pers_d[i] for i in range(d_l-int_trunc,d_l)] 113 | else: 114 | pers_d_trunc = pers_d 115 | st_trunc_pers = st_trunc_pers + [(d,(l[0],l[1])) for l in pers_d_trunc] 116 | return(st_trunc_pers) 117 | 118 | 119 | -------------------------------------------------------------------------------- /utils/KeplerMapperVisuFromTxtFile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | from gudhi.cover_complex import _save_to_html 5 | 6 | """This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. 7 | See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. 8 | Author(s): Mathieu Carriere 9 | 10 | Copyright (C) 2017 Inria 11 | 12 | Modification(s): 13 | - YYYY/MM Author: Description of the modification 14 | """ 15 | 16 | __author__ = "Mathieu Carriere" 17 | __copyright__ = "Copyright (C) 2017 Inria" 18 | __license__ = "GPL v3" 19 | 20 | parser = argparse.ArgumentParser(description='Creates an html Keppler Mapper ' 21 | 'file to visualize a SC.txt file.', 22 | epilog='Example: ' 23 | './KeplerMapperVisuFromTxtFile.py ' 24 | '-f ../../data/points/human.off_sc.txt' 25 | '- Constructs an human.off_sc.html file.') 26 | parser.add_argument("-f", "--file", type=str, required=True) 27 | 28 | args = parser.parse_args() 29 | 30 | with open(args.file, 'r') as f: 31 | 32 | dat = f.readline() 33 | lens = f.readline() 34 | color = f.readline(); 35 | param = [float(i) for i in f.readline().split(" ")] 36 | nums = [int(i) for i in f.readline().split(" ")] 37 | points = [[float(j) for j in f.readline().split(" ")] for i in range(0, nums[0])] 38 | edges = [[int(j) for j in f.readline().split(" ")] for i in range(0, nums[1])] 39 | html_output_filename = args.file.rsplit('.', 1)[0] + '.html' 40 | 41 | f.close() 42 | 43 | _save_to_html(dat, lens, color, param, points, edges, html_output_filename) 44 | -------------------------------------------------------------------------------- /utils/broken_links_scraper.py: -------------------------------------------------------------------------------- 1 | # This file is released under MIT licence, see LICENSE file. 2 | # Author(s): Hind Montassif 3 | # 4 | # Copyright (C) 2021 Inria 5 | 6 | import re 7 | import requests 8 | import sys 9 | from urllib.request import urlopen 10 | from colorama import Fore 11 | 12 | log_verbose = False # Not verbose by default (only handles 404 errors) ; if set to True, the other errors types are displayed among other traces 13 | 14 | if len(sys.argv) >= 2: 15 | if sys.argv[1] == "verbose": 16 | log_verbose = True 17 | else : 18 | print("The only supported additional argument is 'verbose'") 19 | exit(1) 20 | 21 | def print_cond(cond, str): 22 | if cond: 23 | print(str) 24 | else: 25 | pass 26 | 27 | exit_status = 0 28 | # Get data from gudhi TDA-tutorial repo README 29 | data = urlopen("https://raw.githubusercontent.com/GUDHI/TDA-tutorial/master/README.md").read().decode('utf-8') 30 | 31 | # Get all websites links (which begin with http or https) 32 | name_regex = "[^]]+" 33 | url_regex = "http[s]?://[^)]+" 34 | 35 | markup_regex = '\[({0})]\(\s*({1})\s*\)'.format(name_regex, url_regex) 36 | 37 | list_http_links = [] 38 | for match in re.findall(markup_regex, data): 39 | if (match[1].find('latex') == -1): 40 | list_http_links.append(match[1]) 41 | 42 | # Check validity of these urls 43 | print_cond(log_verbose, Fore.CYAN + "Checking websites URLs status code ... " + Fore.RESET) 44 | 45 | all_good = True 46 | for url in list_http_links: 47 | try: 48 | r = requests.head(url) 49 | if (r.status_code != 200): 50 | all_good = False 51 | if (r.status_code == 404): 52 | print(Fore.RED + "{} is not working. The returned status code is {:4d}".format(url, r.status_code) + Fore.RESET) 53 | exit_status = 1 54 | else: 55 | print_cond(log_verbose, Fore.LIGHTYELLOW_EX + "{} may not be working. The returned status code is {:4d}".format(url, r.status_code) + Fore.RESET) 56 | except requests.ConnectionError: 57 | print_cond(log_verbose, Fore.RED + "Failed to connect to " + url + Fore.RESET) 58 | 59 | if all_good: 60 | print_cond(log_verbose, Fore.GREEN + "All links to websites work fine !" + Fore.RESET) 61 | 62 | 63 | # Get all jupyter notebooks included in the README 64 | start = '\(' 65 | end = '.ipynb' 66 | 67 | # Find the name of the tutorial 68 | list_nb = re.findall('%s(.*)%s' % (start, end), data) 69 | # Add ipynb extension to the filenames 70 | list_nb = [x + ".ipynb" for x in list_nb] 71 | 72 | # Check the notebooks links 73 | print_cond(log_verbose, Fore.CYAN + "Checking notebooks URLs status code ... " + Fore.RESET) 74 | 75 | raw_nb_url = [] 76 | all_good = True 77 | for nb in list_nb: 78 | # Check that the notebook is not already given as a complete url 79 | if nb.find("http") == -1: 80 | url = "https://github.com/GUDHI/TDA-tutorial/blob/master/"+nb 81 | try: 82 | r = requests.head(url) 83 | if (r.status_code != 200): 84 | all_good = False 85 | if (r.status_code == 404): 86 | print(Fore.RED + "{} is not working. The returned status code is {:4d}".format(url, r.status_code) + Fore.RESET) 87 | exit_status = 1 88 | else: 89 | print_cond(log_verbose, Fore.LIGHTYELLOW_EX + "{} may not be working. The returned status code is {:4d}".format(url, r.status_code) + Fore.RESET) 90 | else: 91 | raw_nb_url.append("https://raw.githubusercontent.com/GUDHI/TDA-tutorial/master/"+nb) 92 | except requests.ConnectionError: 93 | print_cond(log_verbose, Fore.RED + "Failed to connect to " + url + Fore.RESET) 94 | 95 | if all_good: 96 | print_cond(log_verbose, Fore.GREEN + "All links to notebooks work fine !" + Fore.RESET) 97 | 98 | # Check links inside notebooks 99 | for nb in raw_nb_url: 100 | all_good = True 101 | print_cond(log_verbose, Fore.CYAN + "Checking URLs status code of notebook " + nb + " ..." + Fore.RESET) 102 | raw_nb_data = urlopen(nb).read().decode('utf-8') 103 | # Beginning with http or https and ending with ' ', '"' or ')' or '\n' or ''' or '>' 104 | url_nb_regex = r"http[s]?://[^)\"\ \\\n\'\>]+" 105 | 106 | for match in re.findall(url_nb_regex, raw_nb_data): 107 | # Remove '.' if it was included in the url (by writer to end the sentence but is not supposed to be there) 108 | if (match.endswith('.')): 109 | match = match[:-1] 110 | # Irrelevant urls; could also add svg etc 111 | if ( match.endswith('.png') | (match.find("mapbox") != -1) ): 112 | continue 113 | # Check that links are not broken 114 | try: 115 | r = requests.head(match) 116 | if (r.status_code != 200): 117 | all_good = False 118 | if (r.status_code == 404): 119 | print(Fore.RED + "{} is not working. The returned status code is {:4d}".format(match, r.status_code) + Fore.RESET) 120 | exit_status = 1 121 | else: 122 | print_cond(log_verbose, Fore.LIGHTYELLOW_EX + "{} may not be working. The returned status code is {:4d}".format(match, r.status_code) + Fore.RESET) 123 | except requests.ConnectionError: 124 | print_cond(log_verbose, Fore.RED + "Failed to connect to " + match + Fore.RESET) 125 | if all_good: 126 | print_cond(log_verbose, Fore.GREEN + "All links in the notebook work fine !" + Fore.RESET) 127 | 128 | exit(exit_status) 129 | -------------------------------------------------------------------------------- /utils/utils_epd.py: -------------------------------------------------------------------------------- 1 | # This file is released under MIT licence, see file LICENSE. 2 | # Author(s): Theo Lacombe 3 | # 4 | # Copyright (C) 2021 Inria 5 | 6 | import numpy as np 7 | import matplotlib.pyplot as plt 8 | from matplotlib.patches import Polygon 9 | import gudhi as gd 10 | 11 | def sample_circle(n): 12 | theta = 2 * np.pi * np.random.rand(n) 13 | x, y = np.cos(theta), np.sin(theta) 14 | return np.array([x, y]).T 15 | 16 | 17 | def sample_torus(n, r1, r2): 18 | theta1 = 2 * np.pi * np.random.rand(n) 19 | theta2 = 2 * np.pi * np.random.rand(n) 20 | 21 | x = (r1 + r2 * np.cos(theta2)) * np.cos(theta1) 22 | y = (r1 + r2 * np.cos(theta2)) * np.sin(theta1) 23 | z = r2 * np.sin(theta2) 24 | 25 | X = np.array([x, y, z]).T 26 | 27 | return X 28 | 29 | 30 | def sample_noise(N, ndim, scale=1., type="uniform"): 31 | ''' 32 | noise sample uniforme on [-scale, scale]^2 or gaussien N(0, scale^2) 33 | ''' 34 | if type=="uniform": 35 | X_noise = scale * (2 * np.random.rand(N, ndim) - 1) 36 | elif type=="gaussian": 37 | X_noise = scale * np.random.randn(N, ndim) 38 | return X_noise 39 | 40 | 41 | def add_noise(X_noise, X): 42 | return np.concatenate([X, X_noise]) 43 | 44 | 45 | # Compute persistence diagram using the Cech filtration 46 | def alphacomplex(X, hdim=1): 47 | ac = gd.AlphaComplex(points=X) 48 | st = ac.create_simplex_tree() 49 | pers = st.persistence(min_persistence=0.0001) 50 | h1 = st.persistence_intervals_in_dimension(hdim) 51 | return np.sqrt(np.array(h1)) # we must sqrt to get Cech dgm 52 | 53 | 54 | def expected_dgm(X, n, k, hdim=1, replace=True): 55 | ''' 56 | Subsample n points in a point cloud X, k times, and return the k computed persistence diagrams. 57 | ''' 58 | N = len(X) # total nb of points 59 | samples = [np.random.choice(N, n, replace=replace) for _ in range(k)] 60 | Xs = [X[sample] for sample in samples] 61 | diags = [alphacomplex(X, hdim=hdim) for X in Xs] 62 | return diags 63 | 64 | 65 | # Discretization utils to plot expected PD in a nice way. 66 | 67 | def discretize_dgm(diag, m=0, M=1, res=30, expo=2., filt=None, sigma=1.): 68 | ''' 69 | Discretize one diagram, returns a 2D-histogram of size (res x res), the grid representing [m, M]^2. 70 | ''' 71 | if diag.size: 72 | h2d = np.histogram2d(diag[:,0], diag[:,1], bins=res, range=[[m, M],[m, M]])[0] 73 | h2d = np.flip(h2d.T, axis=0) 74 | if filt=="gaussian": 75 | h2d = gaussian_filter(h2d, sigma=sigma) 76 | return h2d 77 | else: 78 | return np.zeros((res, res)) 79 | 80 | def tohist(diags, m=0, M=1, res=30, expo=2.,filt=None, sigma=1.): 81 | ''' 82 | Take a list of observed diagrams 'diags' and return an histogram 83 | which is an estimator of E(Dgm(X_n)) for some integer n 84 | ''' 85 | 86 | output = [discretize_dgm(diag, m=m, M=M, res=res, expo=expo, filt=filt, sigma=sigma) 87 | for diag in diags] 88 | return np.mean(output, axis=0) 89 | 90 | 91 | def plot3d(X, X_noise): 92 | from mpl_toolkits.mplot3d import Axes3D 93 | fig = plt.figure() 94 | ax = fig.add_subplot(111, projection='3d') 95 | ax.scatter(X[:,0], X[:,1], X[:,2], marker='o', color='blue') 96 | ax.scatter(X_noise[:,0], X_noise[:,1], X_noise[:,2], marker='x', color='red') 97 | 98 | def plot2d(X, X_noise): 99 | fig = plt.figure() 100 | ax = fig.add_subplot(111) 101 | ax.scatter(X[:,0], X[:,1], marker='x', color='blue') 102 | ax.scatter(X_noise[:,0], X_noise[:,1], marker='x', color='red') 103 | ax.set_aspect("equal") 104 | 105 | 106 | def plot_object(X, X_noise): 107 | if X.ndim == 2: 108 | plot2d(X, X_noise) 109 | elif X.ndim == 3: 110 | plot3d(X, X_noise) 111 | else: 112 | print("Unknown number of dimension. Input should be a 2D or a 3D point cloud.") 113 | 114 | 115 | def plot_hist(h, ax=None): 116 | if ax is None: 117 | fig = plt.figure() 118 | ax = fig.add_subplot(111) 119 | ax.imshow(h, cmap='hot_r', interpolation='bilinear') 120 | L = h.shape[0] 121 | ax.set_xticks([]) 122 | ax.set_yticks([]) 123 | ax.set_xlabel("Births", fontsize=18) 124 | ax.set_ylabel("Deaths", fontsize=18) 125 | ax.add_patch(Polygon([[L,-1], [L,L], [-1,L]], fill=True, color='lightgrey')) 126 | ax.set_title("Expected PD", fontsize=24) 127 | 128 | def plot_dgm(dgm_true, dgm_tot, m, M, ax=None): 129 | if ax is None: 130 | fig = plt.figure() 131 | ax = fig.add_subplot(111) 132 | x, y = dgm_true[:,0], dgm_true[:,1] 133 | ax.scatter(x, y, marker='o', color='blue', label='true dgm') 134 | ax.scatter(dgm_tot[:,0], dgm_tot[:,1], marker='x', color='red', label='total dgm') 135 | ax.set_xlim(m,M) 136 | ax.set_ylim(m,M) 137 | ax.add_patch(Polygon([[m, m], [M, m], [M, M]], fill=True, color='lightgrey')) 138 | ax.set_aspect("equal") 139 | ax.set_xlabel("Births", fontsize=18) 140 | ax.set_ylabel("Deaths", fontsize=18) 141 | 142 | ax.legend() 143 | ax.set_title("Diagrams", fontsize=24) 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /utils/utils_quantization.py: -------------------------------------------------------------------------------- 1 | # This file is released under MIT licence, see file LICENSE. 2 | # Author(s): Theo Lacombe 3 | # 4 | # Copyright (C) 2021 Inria 5 | 6 | import numpy as np 7 | from scipy.spatial import Voronoi, voronoi_plot_2d 8 | import scipy.spatial.distance as sc 9 | import matplotlib.pyplot as plt 10 | import matplotlib.patches as mpatches 11 | import gudhi as gd 12 | 13 | 14 | def _fparab(a,b,x): 15 | return (x - a)**2 / (2 * b) + (b / 2) 16 | 17 | 18 | def _rotate(t): 19 | res = np.dot(t, np.sqrt(2)/2 * np.array([[1, 1],[-1, 1]])) 20 | return res 21 | 22 | 23 | def _parab(c): 24 | a, b = c 25 | def P(x): 26 | return _fparab(a,b,x) # (x**2 - 2 * a * x + b**2 + a**2)/(2 * b) 27 | return P 28 | 29 | 30 | def plot_partition_codebook(cs): 31 | xmin, xmax = -7, 3 32 | ymin, ymax = -2, 8 33 | 34 | x = np.linspace(-10, 10, 100) 35 | ys = np.array([_parab(c)(x) for c in cs]) 36 | miny = np.min(ys, axis=0) 37 | 38 | r_cs = _rotate(cs) 39 | 40 | vor = Voronoi(r_cs) 41 | 42 | fig, ax = plt.subplots(figsize=(6,6)) 43 | 44 | voronoi_plot_2d(vor, ax, show_points=False, show_vertices=False) 45 | ax.scatter(r_cs[:,0], r_cs[:,1], marker='o', c='b') 46 | 47 | ax.annotate('$c_j$', r_cs[0]+[0.2,0.2], c='blue', fontsize=24) 48 | #ax.annotate('$c_2$', r_cs[2]+[0.2,0.2], c='green', fontsize=24) 49 | #ax.annotate('$V_j(\mathbf{c})$', r_cs[1]+[-0.2,1.9], c='blue', fontsize=24) 50 | #ax.annotate('$V_{k+1}(\mathbf{c})$', r_cs[1]+[2.,-2], c='black', fontsize=24, rotation=45) 51 | 52 | tmp = np.zeros((len(x), 2)) 53 | tmp[:,0] = x 54 | tmp[:,1] = miny 55 | r_parab = _rotate(tmp) 56 | ax.plot(r_parab[:,0], r_parab[:,1], linestyle='dashed', color='black', linewidth=3) 57 | 58 | ax.set_aspect('equal') 59 | ax.fill_between(r_parab[:60,0],y1=r_parab[:60,0],y2=r_parab[:60,1], color='white', alpha=1, zorder=3) 60 | ax.fill_betweenx(r_parab[59:,1],x1=r_parab[59:,1],x2=r_parab[59:,0], color='white', alpha=1, zorder=3) 61 | ax.add_patch(mpatches.Polygon([[0,0], [0,r_parab[59,1]], [r_parab[59,1], r_parab[59,1]]], fill=True, color='white', alpha=1, zorder=3)) 62 | ax.add_patch(mpatches.Polygon([[ymin,ymin], [xmax,ymin], [xmax, xmax]], fill=True, color='lightgrey', alpha=1,zorder=3)) 63 | ax.plot([min(xmin,ymin), max(xmax,ymax)], [min(xmin,ymin), max(xmax,ymax)], color='k', linewidth=3,zorder=3) 64 | ax.annotate('$\partial \Omega$', [-1.3, -1.9], fontsize=24) 65 | #ax.annotate('$N(\mathbf{c})$', [-6.5,0], fontsize=24, rotation=45) 66 | 67 | ax.set_axis_off() 68 | ax.set_ylim(ymin,ymax) 69 | ax.set_xlim(xmin, xmax) 70 | 71 | 72 | def plot_dgm(dgm, box=None, ax=None, color="blue", label='diagram', alpha=None): 73 | if ax is None: 74 | fig = plt.figure() 75 | ax = fig.add_subplot(111) 76 | if dgm.size: 77 | x, y = dgm[:, 0], dgm[:, 1] 78 | ax.scatter(x, y, marker='o', color=color, label=label, alpha=alpha) 79 | if box is None: 80 | if dgm.size: 81 | m, M = np.min(dgm) - 0.1, np.max(dgm) + 0.1 82 | else: 83 | m, M = 0, 1 84 | else: 85 | m, M = box 86 | ax.set_xlim(m, M) 87 | ax.set_ylim(m, M) 88 | ax.add_patch(mpatches.Polygon([[m, m], [M, m], [M, M]], fill=True, color='lightgrey')) 89 | ax.set_aspect("equal") 90 | ax.set_xlabel("Birth", fontsize=24) 91 | ax.set_ylabel("Death", fontsize=24) 92 | # ax.legend() 93 | 94 | 95 | ######################## 96 | ### Experiment utils ### 97 | ######################## 98 | 99 | 100 | def _sample_torus(n, r1, r2, radius_eps, ambiant_eps): 101 | # Sample points uniformly on a torus of big radius r1 and small radius r2 102 | theta1 = 2 * np.pi * np.random.rand(n) 103 | theta2 = 2 * np.pi * np.random.rand(n) 104 | 105 | r1 = r1 + radius_eps * (2 * np.random.rand() - 1) 106 | r2 = r2 + radius_eps * (2 * np.random.rand() - 1) 107 | 108 | x = (r1 + r2 * np.cos(theta2)) * np.cos(theta1) 109 | y = (r1 + r2 * np.cos(theta2)) * np.sin(theta1) 110 | z = r2 * np.sin(theta2) 111 | 112 | X = np.array([x, y, z]).T 113 | 114 | X = X + ambiant_eps * (2 * np.random.rand(n,3) - 1) 115 | 116 | return X 117 | 118 | 119 | def _compute_pd(X, hdim=1, min_persistence=0.0001, mode="alpha", rotate=False): 120 | if mode == "alpha": 121 | ac = gd.AlphaComplex(points=X) 122 | st = ac.create_simplex_tree() 123 | elif mode == "rips": 124 | ac = gd.RipsComplex(points=X) 125 | st = ac.create_simplex_tree(max_dimension=2) 126 | pers = st.persistence(min_persistence=min_persistence) 127 | h1 = st.persistence_intervals_in_dimension(hdim) 128 | if mode == "alpha": 129 | h1 = np.sqrt(np.array(h1)) 130 | if rotate: 131 | h1[:, 1] = h1[:, 1] - h1[:, 0] 132 | return h1 133 | else: 134 | return np.array(h1) / 2 # to make it comparable with Cech 135 | 136 | 137 | def build_dataset(K, params): 138 | average_nb_pts = params['nb_points'] 139 | ns = np.random.poisson(lam=average_nb_pts, size=K) 140 | r1, r2 = params['r1'], params['r2'] 141 | radius_eps = params['radius_eps'] 142 | ambiant_eps = params['ambiant_eps'] 143 | Xs = [_sample_torus(n, r1, r2, radius_eps, ambiant_eps) for n in ns] 144 | diags = [_compute_pd(X) for X in Xs] 145 | return Xs, diags 146 | 147 | 148 | ############################## 149 | ### Quantization algorithm ### 150 | ############################## 151 | 152 | 153 | 154 | 155 | def _dist_to_diag(X, internal_p): 156 | return ((X[:, 1] - X[:, 0]) * 2 ** (1. / internal_p - 1)) 157 | 158 | 159 | def _build_dist_matrix(X, Y, order=2., internal_p=2): 160 | ''' 161 | :param X: (n x 2) numpy.array encoding the (points of the) first diagram. 162 | :param Y: (m x 2) numpy.array encoding the second diagram. 163 | :param order: exponent for the Wasserstein metric. 164 | :param internal_p: Ground metric (i.e. norm L^p). 165 | :returns: (n+1) x (m+1) np.array encoding the cost matrix C. 166 | For 0 <= i < n, 0 <= j < m, C[i,j] encodes the distance between X[i] and Y[j], 167 | while C[i, m] (resp. C[n, j]) encodes the distance (to the p) between X[i] (resp Y[j]) 168 | and its orthogonal projection onto the diagonal. 169 | note also that C[n, m] = 0 (it costs nothing to move from the diagonal to the diagonal). 170 | ''' 171 | Cxd = _dist_to_diag(X, internal_p=internal_p)**order #((X[:, 1] - X[:,0]) * 2 ** (1./internal_p - 1))**order 172 | Cdy = _dist_to_diag(Y, internal_p=internal_p)**order #((Y[:, 1] - Y[:,0]) * 2 ** (1./internal_p - 1))**order 173 | if np.isinf(internal_p): 174 | C = sc.cdist(X, Y, metric='chebyshev') ** order 175 | else: 176 | C = sc.cdist(X, Y, metric='minkowski', p=internal_p) ** order 177 | 178 | Cf = np.hstack((C, Cxd[:, None])) 179 | Cdy = np.append(Cdy, 0) 180 | 181 | Cf = np.vstack((Cf, Cdy[None, :])) 182 | 183 | return Cf 184 | 185 | 186 | def _get_cells(X, c, withdiag, internal_p): 187 | """ 188 | X size (n x 2) 189 | c size (k x 2) 190 | withdiag: boolean 191 | returns: list of size k or (k+1) s.t list[j] corresponds to the points in X which are close to c[j]. 192 | with the convention c[k] <=> the diagonal. 193 | """ 194 | M = _build_dist_matrix(X, c, internal_p=internal_p) # Note: Order is useless here 195 | if withdiag: 196 | a = np.argmin(M[:-1, :], axis=1) 197 | else: 198 | a = np.argmin(M[:-1, :-1], axis=1) 199 | 200 | k = len(c) 201 | 202 | cells = [X[a == j] for j in range(k)] 203 | 204 | if withdiag: 205 | cells.append(X[a == k]) # this is the (k+1)-th centroid corresponding to the diagonal 206 | 207 | return cells 208 | 209 | 210 | def _get_cost_Rk(X, c, withdiag, order, internal_p): 211 | cells = _get_cells(X, c, withdiag, internal_p=internal_p) 212 | k = len(c) 213 | 214 | cost = 0 215 | 216 | if order == np.infty and withdiag: 217 | for cells_j, c_j in zip(cells, c): 218 | if len(cells_j) == 0: 219 | pass 220 | else: 221 | cost_j = np.max(np.linalg.norm(cells_j - c_j, ord=internal_p, axis=1)) 222 | cost = max(cost, cost_j) 223 | if len(cells[k]) == 0: 224 | pass 225 | else: 226 | dists_diag = _dist_to_diag(cells[k], internal_p=internal_p) #**order 227 | cost_diag = np.max(dists_diag) # ** (1. / order) 228 | cost = max(cost, cost_diag) 229 | return cost 230 | 231 | for cells_j, c_j in zip(cells, c): 232 | cost_j = np.linalg.norm(np.linalg.norm(cells_j - c_j, ord=internal_p, axis=1), ord=order)**order 233 | cost += cost_j 234 | 235 | if withdiag: 236 | dists_to_diag = dist_to_diag(cells[k], internal_p=internal_p)**order 237 | cost_diag = np.sum(dists_to_diag) #** (1. / order) 238 | cost += cost_diag 239 | 240 | return cost #** (1./order) 241 | 242 | 243 | def _from_batch(Xs, batches_indices): 244 | X_batch = np.concatenate([Xs[i] for i in batches_indices if Xs[i].ndim==2]) 245 | return X_batch 246 | 247 | 248 | def init_c(list_diags, k, internal_p=2): 249 | dgm = list_diags[0] 250 | w = _dist_to_diag(dgm, internal_p) 251 | s = np.argsort(w) 252 | c0 = dgm[s[-k:]] 253 | return c0 254 | 255 | 256 | def quantization(Xs, batch_size, c0, withdiag, order=2., internal_p=2.): 257 | #np.random.shuffle(Xs) 258 | k = len(c0) 259 | c_current = c0.copy() 260 | n = len(Xs) 261 | batches = np.arange(0, n, dtype=int).reshape(int(n / batch_size), 2, int(batch_size / 2)) 262 | 263 | nb_step = len(batches) 264 | 265 | positions = [c_current.copy()] 266 | 267 | for t in range(nb_step): 268 | X_bar_t_1 = _from_batch(Xs, batches[t, 0]) 269 | X_bar_t_2 = _from_batch(Xs, batches[t, 1]) 270 | 271 | cells_1 = _get_cells(X_bar_t_1, c_current, withdiag=withdiag, internal_p=internal_p) 272 | cells_2 = _get_cells(X_bar_t_2, c_current, withdiag=withdiag, internal_p=internal_p) 273 | 274 | s1, s2 = len(batches[t, 0]), len(batches[t, 1]) 275 | if order == 2.: 276 | for j in range(k): 277 | lc1 = len(cells_1[j]) 278 | if lc1 > 0: 279 | grad = np.sum(c_current[j] - cells_2[j], axis=0) / s2 280 | c_current[j] = c_current[j] - grad / ((t + 1) * len(cells_1[j]) / s1) 281 | else: 282 | raise NotImplemented('Order %s is not available yet. Only order=2. is valid in this notebook' %order) 283 | positions.append(c_current.copy()) 284 | 285 | return positions 286 | 287 | 288 | ########################### 289 | ### Plot quantiz result ### 290 | ########################### 291 | def plot_result_quantiz(diags, c_final_diag, c_final_vanilla, c0): 292 | low, high = -.2, 3.2 293 | 294 | fig, ax2 = plt.subplots(figsize=(6,6)) 295 | 296 | for pd in diags: 297 | ax2.scatter(pd[:,0], pd[:,1], marker='o', c='orange', alpha=0.1) 298 | ax2.add_patch(mpatches.Polygon([[low,low], [high,low], [high,high]], fill=True, color='lightgrey')) 299 | 300 | ax2.scatter(c_final_diag[:,0], c_final_diag[:,1], marker='^', color='red', s=100, 301 | label='$\mathbf{c}^{\mathrm{output}}$') 302 | 303 | ax2.scatter(c_final_vanilla[:,0], c_final_vanilla[:,1], marker='o', color='blue', label='Output w/out diag cell') 304 | 305 | ax2.scatter(c0[:,0], c0[:,1], marker='x', color='black', label='initial position') 306 | ax2.legend(fontsize=12) 307 | ax2.set_xlim(low, high) 308 | ax2.set_ylim(low, high) 309 | ax2.set_xlabel('Birth',fontsize=24) 310 | ax2.set_ylabel('Death',fontsize=24) 311 | ax2.set_aspect('equal') 312 | 313 | --------------------------------------------------------------------------------