├── .gitignore ├── CMakeLists.txt ├── FindNumPy.cmake ├── LICENSE ├── README.md ├── ext ├── ANN │ ├── ANN.cpp │ ├── ANN │ │ ├── ANN.h │ │ ├── ANNperf.h │ │ └── ANNx.h │ ├── CMakeLists.txt │ ├── Copyright.txt │ ├── License.txt │ ├── Make-config │ ├── ReadMe.txt │ ├── bd_fix_rad_search.cpp │ ├── bd_pr_search.cpp │ ├── bd_search.cpp │ ├── bd_tree.cpp │ ├── bd_tree.h │ ├── brute.cpp │ ├── kd_dump.cpp │ ├── kd_fix_rad_search.cpp │ ├── kd_fix_rad_search.h │ ├── kd_pr_search.cpp │ ├── kd_pr_search.h │ ├── kd_search.cpp │ ├── kd_search.h │ ├── kd_split.cpp │ ├── kd_split.h │ ├── kd_tree.cpp │ ├── kd_tree.h │ ├── kd_util.cpp │ ├── kd_util.h │ ├── perf.cpp │ ├── pr_queue.h │ ├── pr_queue_k.h │ └── src │ │ └── Makefile ├── CMakeLists.txt └── geom_dist │ ├── README_bottleneck │ ├── README_wasserstein │ ├── bottleneck │ ├── CMakeLists.txt │ ├── include │ │ ├── ANN │ │ │ ├── ANN.h │ │ │ ├── ANNperf.h │ │ │ ├── ANNx.h │ │ │ ├── bd_tree.h │ │ │ ├── kd_fix_rad_search.h │ │ │ ├── kd_pr_search.h │ │ │ ├── kd_search.h │ │ │ ├── kd_split.h │ │ │ ├── kd_tree.h │ │ │ ├── kd_util.h │ │ │ ├── pr_queue.h │ │ │ └── pr_queue_k.h │ │ ├── basic_defs_bt.h │ │ ├── bottleneck.h │ │ ├── bound_match.h │ │ ├── def_debug.h │ │ └── neighb_oracle.h │ ├── lib │ │ └── dummy │ └── src │ │ ├── ann │ │ ├── ANN.cpp │ │ ├── bd_fix_rad_search.cpp │ │ ├── bd_pr_search.cpp │ │ ├── bd_search.cpp │ │ ├── bd_tree.cpp │ │ ├── kd_dump.cpp │ │ ├── kd_fix_rad_search.cpp │ │ ├── kd_pr_search.cpp │ │ ├── kd_search.cpp │ │ ├── kd_split.cpp │ │ ├── kd_tree.cpp │ │ └── kd_util.cpp │ │ ├── basic_defs.cpp │ │ ├── bottleneck.cpp │ │ ├── bound_match.cpp │ │ ├── brute.cpp │ │ └── neighb_oracle.cpp │ └── wasserstein │ ├── CMakeLists.txt │ ├── example │ └── wasserstein_dist.cpp │ ├── include │ ├── auction_oracle.h │ ├── auction_runner.h │ ├── basic_defs_ws.h │ ├── def_debug.h │ ├── dnn │ │ ├── geometry │ │ │ └── euclidean-fixed.h │ │ ├── local │ │ │ ├── kd-tree.h │ │ │ ├── kd-tree.hpp │ │ │ └── search-functors.h │ │ ├── parallel │ │ │ ├── tbb.h │ │ │ └── utils.h │ │ └── utils.h │ └── wasserstein.h │ ├── license.txt │ └── src │ ├── auction_oracle.cpp │ ├── basic_defs.cpp │ └── wasserstein.cpp ├── geometry ├── CMakeLists.txt ├── SparseVector.cpp ├── SparseVector.h ├── Vector.cpp ├── Vector.h ├── covertree.cpp ├── covertree.h └── point_incs.h ├── python └── persistence │ ├── ActivitySegments.py │ ├── AverageKernel.py │ ├── BirdSoundsSegments.py │ ├── BottleneckDistances.py │ ├── CMUMocapSegments.py │ ├── ChaosPost.py │ ├── ChaoticInvariantFeatures.py │ ├── ConfigViewer.py │ ├── CrossValidation.py │ ├── Datatypes │ ├── Configuration.py │ ├── Distances.py │ ├── Features.py │ ├── JSONObject.py │ ├── Kernel.py │ ├── Learning.py │ ├── PersistenceDiagrams.py │ ├── Segments.py │ ├── TrainTestPartitions.py │ └── __init__.py │ ├── DistanceLearning.py │ ├── EEGEyeSegments.py │ ├── EuclideanDistances.py │ ├── FeatureLearning.py │ ├── KernelLearning.py │ ├── KitchenMocapSegments.py │ ├── LandscapeDistances.py │ ├── NormalizePost.py │ ├── PAMAPSegments.py │ ├── ParseConfigurations.py │ ├── PartitionData.py │ ├── PersistenceGenerator.py │ ├── PersistenceKernel.py │ ├── RBFKernel.py │ ├── README.md │ ├── ScaleSpaceSimilarity.py │ ├── UCRSegments.py │ ├── WalkingSegments.py │ ├── WassersteinDistances.py │ ├── __init__.py │ ├── class_hierarchy.pdf │ ├── segment_persistence_plotter.png │ └── tutorial.md ├── scripts ├── ChaosPost_stats.py ├── activity_recognition.py ├── bar_plot_from_csv.py ├── distributed_compute_template.py ├── learning_from_cross_validation.py ├── learning_stats.py ├── learning_unit_test.py ├── migrate_data │ ├── distances.py │ ├── kernel.py │ ├── move_data.py │ └── persistences.py ├── pd_plotter.py ├── pd_plotter_series.py ├── persistence_bottleneck_distance.py ├── persistence_density.py ├── persistence_segment_size_evaluation.py ├── plots │ ├── activity_persistence.py │ ├── distance_mds.py │ ├── distance_vs_label.py │ ├── explore_persistence.py │ ├── kNN_persistence_plotter.py │ ├── neighbor_distance.py │ ├── persistence_density.py │ ├── persistence_kde.py │ ├── persistence_kde_anim.py │ ├── persistence_sample_plot.py │ ├── plot_activity.py │ ├── plot_best_distances_segment.py │ ├── plot_distance_2d.py │ ├── plot_learning.py │ ├── plot_learning_errorbars.py │ ├── plot_learning_stats.py │ ├── plot_multi_persistence.py │ ├── plot_persistence.py │ ├── plot_persistence_distance.py │ ├── plot_ucr_learning.py │ ├── segment_persistence_plotter.py │ ├── test_similarity.py │ └── ucr_csv_results.py ├── rips_plotter.py ├── run-config.py ├── scatter_anim_example.py ├── simple_time_series_plotter.py ├── sparse_vs_full_rips.py ├── window_data.py ├── wrong.py └── zero_persistence_graph.py └── topology ├── CMakeLists.txt ├── ComputationTimer.cpp ├── ComputationTimer.h ├── bottleneck_distance.cpp ├── bottleneck_distance.h ├── distance_learning ├── knn_persistence_classifier.cpp └── knn_persistence_classifier.h ├── dtw.h ├── dtw_python.cpp ├── dtw_python.hpp ├── euclidean_space.cpp ├── euclidean_space.h ├── filtration.cpp ├── filtration.h ├── fps_rips_filtration.cpp ├── fps_rips_filtration.h ├── generalized_metric_space.cpp ├── generalized_metric_space.h ├── hungarianC.h ├── landscape_distance.cpp ├── landscape_distance.h ├── metric_space.cpp ├── metric_space.h ├── persistence.cpp ├── persistence.h ├── persistenceBarcode.h ├── persistenceLandscape.h ├── persistence_dataset.cpp ├── persistence_dataset.h ├── persistence_diagram.cpp ├── persistence_diagram.h ├── python └── py_persistence.cpp ├── relaxed_metric_space.cpp ├── relaxed_metric_space.h ├── rips_filtration.cpp ├── rips_filtration.h ├── rips_python.cpp ├── rips_python.hpp ├── scale_space_kernel.cpp ├── scale_space_kernel.h ├── segment_dataset.cpp ├── segment_dataset.h ├── simplex.cpp ├── simplex.h ├── sparse_persistence.cpp ├── sparse_persistence.h ├── sparse_rips_filtration.cpp ├── sparse_rips_filtration.h ├── zero_persistence.cpp ├── zero_persistence.h ├── zero_persistence_python.cpp └── zero_persistence_python.h /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | Makefile 4 | cmake_install.cmake 5 | *.a 6 | *.so 7 | ext/geom_dist/wasserstein/wasserstein_dist 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(tstop) 2 | cmake_minimum_required(VERSION 2.8) 3 | LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}) 4 | FIND_PACKAGE(Boost REQUIRED COMPONENTS serialization) 5 | FIND_PACKAGE(PythonLibs REQUIRED) 6 | message("Include dirs of boost: " ${Boost_INCLUDE_DIRS} ) 7 | message("Libs of boost: " ${Boost_LIBRARIES} ) 8 | message("Include dirs of Python: " ${PYTHON_INCLUDE_DIRS} ) 9 | message("Libs of Python: " ${PYTHON_LIBRARIES} ) 10 | 11 | FIND_PACKAGE(OpenMP) 12 | if(OPENMP_FOUND) 13 | message("Got OpenMP!") 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 16 | endif() 17 | 18 | INCLUDE_DIRECTORIES(${tstop_SOURCE_DIR} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} /usr/include/eigen3) 19 | SUBDIRS(ext geometry topology) 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Time-series Topology (TS-TOP) 2 | Release Date: June 2016 3 | 4 | This project contains the source code and datasets for the time-series topology data analysis tool suite for time-series characterization and classification as described in the [paper](http://www.cv-foundation.org//openaccess/content_cvpr_2016_workshops/w23/papers/Seversky_On_Time-Series_Topological_CVPR_2016_paper.pdf) : 5 | 6 | Seversky, Lee M., Shelby Davis, and Matthew Berger. 7 | "On Time-Series Topological Data Analysis: New Data and Opportunities." 8 | Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition Workshops. 2016. 9 | 10 | 11 | If you use the software or associated data please use the following citation: 12 | 13 | ``` 14 | @InProceedings{Seversky_2016_CVPR_Workshops, 15 | author = {Seversky, Lee M. and Davis, Shelby and Berger, Matthew}, 16 | title = {On Time-Series Topological Data Analysis: New Data and Opportunities}, 17 | booktitle = {The IEEE Conference on Computer Vision and Pattern Recognition (CVPR) Workshops}, 18 | month = {June}, 19 | year = {2016} 20 | } 21 | ``` 22 | 23 | # Installation 24 | 25 | ## Exterior Sources to be downloaded: 26 | 27 | From Arnur Nigmetov (Graz Unvirsity of Technology, Graz, Austria) 28 | 29 | Download and Extract 30 | [Hera] (https://bitbucket.org/grey_narn/hera/downloads) 31 | 32 | Move `geom_bottleneck` to `tstop/ext/geom_dist/bottleneck` 33 | 34 | Move `geom_matching` to `tstop/ext/geom_dist/wasserstein` 35 | 36 | 37 | From David M. Mount and Sunil Arya (University of Maryland, College Park, Maryland) 38 | 39 | Download [ANN](http://www.cs.umd.edu/~mount/ANN/) and extract to `tstop/ext/ANN` 40 | 41 | ## Building 42 | 43 | Install [boost](http://www.boost.org) python and serialization libraries, 44 | [scikit-learn](http://scikit-learn.org/stable/install.html), 45 | [matplotlib](http://matplotlib.org/), 46 | [Eigen 3](http://eigen.tuxfamily.org/index.php), 47 | [cmake](https://cmake.org/), and optionally [wxPython](https://wxpython.org/) 48 | On machines with `apt-get`: 49 | ```sh 50 | $ sudo apt-get install libboost-python-dev libboost-serialization-dev python-matplotlib python-sklearn python-wxgtk3.0-dev libeigen3-dev cmake 51 | ``` 52 | 53 | 54 | Run in `tstop` 55 | ```sh 56 | $ cmake -DCMAKE_BUILD_TYPE=release . 57 | $ make 58 | ``` 59 | 60 | # Running 61 | 62 | Add `tstop/python` to the `PYTHONPATH` environment variable 63 | 64 | # Documentation and Tutorial 65 | 66 | For detailed documentation please see: [Documentation] (python/persistence/README.md) 67 | 68 | For a short tutorial please see: [Time-series Topology Tutorial] (python/persistence/tutorial.md) 69 | 70 | 71 | # Data 72 | 73 | Time-series datasets and precomputed topological features: [Download] (https://drive.google.com/open?id=0B-eHoAvCU5B5M3dMS3VQWU5IRzA) 74 | 75 | -------------------------------------------------------------------------------- /ext/ANN/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(${tstop_SOURCE_DIR}/ext/ANN) 2 | SET(ann_sources 3 | ANN.cpp brute.cpp kd_tree.cpp kd_util.cpp kd_split.cpp 4 | kd_dump.cpp kd_search.cpp kd_pr_search.cpp kd_fix_rad_search.cpp 5 | bd_tree.cpp bd_search.cpp bd_pr_search.cpp bd_fix_rad_search.cpp 6 | perf.cpp 7 | kd_tree.h kd_split.h kd_util.h kd_search.h 8 | kd_pr_search.h kd_fix_rad_search.h pr_queue.h pr_queue_k.h 9 | ) 10 | 11 | ADD_LIBRARY(ann ${ann_sources}) 12 | -------------------------------------------------------------------------------- /ext/ANN/Copyright.txt: -------------------------------------------------------------------------------- 1 | ANN: Approximate Nearest Neighbors 2 | Version: 1.1.2 3 | Release Date: Jan 27, 2010 4 | ---------------------------------------------------------------------------- 5 | Copyright (c) 1997-2010 University of Maryland and Sunil Arya and David 6 | Mount All Rights Reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU Lesser Public License as published by the 10 | Free Software Foundation; either version 2.1 of the License, or (at your 11 | option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser Public License for more details. 17 | 18 | A copy of the terms and conditions of the license can be found in 19 | License.txt or online at 20 | 21 | http://www.gnu.org/copyleft/lesser.html 22 | 23 | To obtain a copy, write to the Free Software Foundation, Inc., 24 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | 26 | Disclaimer 27 | ---------- 28 | The University of Maryland and the authors make no representations about 29 | the suitability or fitness of this software for any purpose. It is 30 | provided "as is" without express or implied warranty. 31 | --------------------------------------------------------------------- 32 | 33 | Authors 34 | ------- 35 | David Mount 36 | Dept of Computer Science 37 | University of Maryland, 38 | College Park, MD 20742 USA 39 | mount@cs.umd.edu 40 | http://www.cs.umd.edu/~mount/ 41 | 42 | Sunil Arya 43 | Dept of Computer Science 44 | Hong University of Science and Technology 45 | Clearwater Bay, HONG KONG 46 | arya@cs.ust.hk 47 | http://www.cs.ust.hk/faculty/arya/ 48 | -------------------------------------------------------------------------------- /ext/ANN/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ANN: Approximate Nearest Neighbors 2 | Version: 1.1.2 3 | Release date: Jan 27, 2010 4 | ---------------------------------------------------------------------------- 5 | Copyright (c) 1997-2010 University of Maryland and Sunil Arya and David 6 | Mount. All Rights Reserved. See Copyright.txt and License.txt for 7 | complete information on terms and conditions of use and distribution of 8 | this software. 9 | ---------------------------------------------------------------------------- 10 | 11 | Authors 12 | ------- 13 | David Mount 14 | Dept of Computer Science 15 | University of Maryland, 16 | College Park, MD 20742 USA 17 | mount@cs.umd.edu 18 | http://www.cs.umd.edu/~mount/ 19 | 20 | Sunil Arya 21 | Dept of Computer Science 22 | Hong University of Science and Technology 23 | Clearwater Bay, HONG KONG 24 | arya@cs.ust.hk 25 | http://www.cs.ust.hk/faculty/arya/ 26 | 27 | Introduction 28 | ------------ 29 | ANN is a library written in the C++ programming language to support both 30 | exact and approximate nearest neighbor searching in spaces of various 31 | dimensions. It was implemented by David M. Mount of the University of 32 | Maryland, and Sunil Arya of the Hong Kong University of Science and 33 | Technology. ANN (pronounced like the name ``Ann'') stands for 34 | Approximate Nearest Neighbors. ANN is also a testbed containing 35 | programs and procedures for generating data sets, collecting and 36 | analyzing statistics on the performance of nearest neighbor algorithms 37 | and data structures, and visualizing the geometric structure of these 38 | data structures. 39 | 40 | The ANN source code and documentation is available from the following 41 | web page: 42 | 43 | http://www.cs.umd.edu/~mount/ANN 44 | 45 | For more information on ANN and its use, see the ``ANN Programming 46 | Manual,'' which is provided with the software distribution. 47 | 48 | ---------------------------------------------------------------------------- 49 | History 50 | Version 0.1 03/04/98 51 | Preliminary release 52 | Version 0.2 06/24/98 53 | Changes for SGI compiler. 54 | Version 1.0 04/01/05 55 | Fixed a number of small bugs 56 | Added dump/load operations 57 | Added annClose to eliminate minor memory leak 58 | Improved compatibility with current C++ compilers 59 | Added compilation for Microsoft Visual Studio.NET 60 | Added compilation for Linux 2.x 61 | Version 1.1 05/03/05 62 | Added make target for Mac OS X 63 | Added fixed-radius range searching and counting 64 | Added instructions on compiling/using ANN on Windows platforms 65 | Fixed minor output bug in ann2fig 66 | Version 1.1.1 08/04/06 67 | Added "planted" distribution 68 | Updated old source comments for GNU LPL. 69 | Version 1.1.2 01/27/10 70 | Fixed minor compilation bugs for new versions of gcc 71 | -------------------------------------------------------------------------------- /ext/ANN/bd_fix_rad_search.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: bd_fix_rad_search.cpp 3 | // Programmer: David Mount 4 | // Description: Standard bd-tree search 5 | // Last modified: 05/03/05 (Version 1.1) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 1.1 05/03/05 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #include "bd_tree.h" // bd-tree declarations 26 | #include "kd_fix_rad_search.h" // kd-tree FR search declarations 27 | 28 | //---------------------------------------------------------------------- 29 | // Approximate searching for bd-trees. 30 | // See the file kd_FR_search.cpp for general information on the 31 | // approximate nearest neighbor search algorithm. Here we 32 | // include the extensions for shrinking nodes. 33 | //---------------------------------------------------------------------- 34 | 35 | //---------------------------------------------------------------------- 36 | // bd_shrink::ann_FR_search - search a shrinking node 37 | //---------------------------------------------------------------------- 38 | 39 | void ANNbd_shrink::ann_FR_search(ANNdist box_dist) 40 | { 41 | // check dist calc term cond. 42 | if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; 43 | 44 | ANNdist inner_dist = 0; // distance to inner box 45 | for (int i = 0; i < n_bnds; i++) { // is query point in the box? 46 | if (bnds[i].out(ANNkdFRQ)) { // outside this bounding side? 47 | // add to inner distance 48 | inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdFRQ)); 49 | } 50 | } 51 | if (inner_dist <= box_dist) { // if inner box is closer 52 | child[ANN_IN]->ann_FR_search(inner_dist);// search inner child first 53 | child[ANN_OUT]->ann_FR_search(box_dist);// ...then outer child 54 | } 55 | else { // if outer box is closer 56 | child[ANN_OUT]->ann_FR_search(box_dist);// search outer child first 57 | child[ANN_IN]->ann_FR_search(inner_dist);// ...then outer child 58 | } 59 | ANN_FLOP(3*n_bnds) // increment floating ops 60 | ANN_SHR(1) // one more shrinking node 61 | } 62 | -------------------------------------------------------------------------------- /ext/ANN/bd_pr_search.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: bd_pr_search.cpp 3 | // Programmer: David Mount 4 | // Description: Priority search for bd-trees 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | //History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #include "bd_tree.h" // bd-tree declarations 26 | #include "kd_pr_search.h" // kd priority search declarations 27 | 28 | //---------------------------------------------------------------------- 29 | // Approximate priority searching for bd-trees. 30 | // See the file kd_pr_search.cc for general information on the 31 | // approximate nearest neighbor priority search algorithm. Here 32 | // we include the extensions for shrinking nodes. 33 | //---------------------------------------------------------------------- 34 | 35 | //---------------------------------------------------------------------- 36 | // bd_shrink::ann_search - search a shrinking node 37 | //---------------------------------------------------------------------- 38 | 39 | void ANNbd_shrink::ann_pri_search(ANNdist box_dist) 40 | { 41 | ANNdist inner_dist = 0; // distance to inner box 42 | for (int i = 0; i < n_bnds; i++) { // is query point in the box? 43 | if (bnds[i].out(ANNprQ)) { // outside this bounding side? 44 | // add to inner distance 45 | inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNprQ)); 46 | } 47 | } 48 | if (inner_dist <= box_dist) { // if inner box is closer 49 | if (child[ANN_OUT] != KD_TRIVIAL) // enqueue outer if not trivial 50 | ANNprBoxPQ->insert(box_dist,child[ANN_OUT]); 51 | // continue with inner child 52 | child[ANN_IN]->ann_pri_search(inner_dist); 53 | } 54 | else { // if outer box is closer 55 | if (child[ANN_IN] != KD_TRIVIAL) // enqueue inner if not trivial 56 | ANNprBoxPQ->insert(inner_dist,child[ANN_IN]); 57 | // continue with outer child 58 | child[ANN_OUT]->ann_pri_search(box_dist); 59 | } 60 | ANN_FLOP(3*n_bnds) // increment floating ops 61 | ANN_SHR(1) // one more shrinking node 62 | } 63 | -------------------------------------------------------------------------------- /ext/ANN/bd_search.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: bd_search.cpp 3 | // Programmer: David Mount 4 | // Description: Standard bd-tree search 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #include "bd_tree.h" // bd-tree declarations 26 | #include "kd_search.h" // kd-tree search declarations 27 | 28 | //---------------------------------------------------------------------- 29 | // Approximate searching for bd-trees. 30 | // See the file kd_search.cpp for general information on the 31 | // approximate nearest neighbor search algorithm. Here we 32 | // include the extensions for shrinking nodes. 33 | //---------------------------------------------------------------------- 34 | 35 | //---------------------------------------------------------------------- 36 | // bd_shrink::ann_search - search a shrinking node 37 | //---------------------------------------------------------------------- 38 | 39 | void ANNbd_shrink::ann_search(ANNdist box_dist) 40 | { 41 | // check dist calc term cond. 42 | if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; 43 | 44 | ANNdist inner_dist = 0; // distance to inner box 45 | for (int i = 0; i < n_bnds; i++) { // is query point in the box? 46 | if (bnds[i].out(ANNkdQ)) { // outside this bounding side? 47 | // add to inner distance 48 | inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdQ)); 49 | } 50 | } 51 | if (inner_dist <= box_dist) { // if inner box is closer 52 | child[ANN_IN]->ann_search(inner_dist); // search inner child first 53 | child[ANN_OUT]->ann_search(box_dist); // ...then outer child 54 | } 55 | else { // if outer box is closer 56 | child[ANN_OUT]->ann_search(box_dist); // search outer child first 57 | child[ANN_IN]->ann_search(inner_dist); // ...then outer child 58 | } 59 | ANN_FLOP(3*n_bnds) // increment floating ops 60 | ANN_SHR(1) // one more shrinking node 61 | } 62 | -------------------------------------------------------------------------------- /ext/ANN/kd_fix_rad_search.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_fix_rad_search.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Standard kd-tree fixed-radius kNN search 5 | // Last modified: 05/03/05 (Version 1.1) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 1.1 05/03/05 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_kd_fix_rad_search_H 26 | #define ANN_kd_fix_rad_search_H 27 | 28 | #include "kd_tree.h" // kd-tree declarations 29 | #include "kd_util.h" // kd-tree utilities 30 | #include "pr_queue_k.h" // k-element priority queue 31 | 32 | #include // performance evaluation 33 | 34 | //---------------------------------------------------------------------- 35 | // Global variables 36 | // These are active for the life of each call to 37 | // annRangeSearch(). They are set to save the number of 38 | // variables that need to be passed among the various search 39 | // procedures. 40 | //---------------------------------------------------------------------- 41 | 42 | extern ANNpoint ANNkdFRQ; // query point (static copy) 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /ext/ANN/kd_pr_search.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_pr_search.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Priority kd-tree search 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_kd_pr_search_H 26 | #define ANN_kd_pr_search_H 27 | 28 | #include "kd_tree.h" // kd-tree declarations 29 | #include "kd_util.h" // kd-tree utilities 30 | #include "pr_queue.h" // priority queue declarations 31 | #include "pr_queue_k.h" // k-element priority queue 32 | 33 | #include // performance evaluation 34 | 35 | //---------------------------------------------------------------------- 36 | // Global variables 37 | // Active for the life of each call to Appx_Near_Neigh() or 38 | // Appx_k_Near_Neigh(). 39 | //---------------------------------------------------------------------- 40 | 41 | extern double ANNprEps; // the error bound 42 | extern int ANNprDim; // dimension of space 43 | extern ANNpoint ANNprQ; // query point 44 | extern double ANNprMaxErr; // max tolerable squared error 45 | extern ANNpointArray ANNprPts; // the points 46 | extern ANNpr_queue *ANNprBoxPQ; // priority queue for boxes 47 | extern ANNmin_k *ANNprPointMK; // set of k closest points 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /ext/ANN/kd_search.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_search.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Standard kd-tree search 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_kd_search_H 26 | #define ANN_kd_search_H 27 | 28 | #include "kd_tree.h" // kd-tree declarations 29 | #include "kd_util.h" // kd-tree utilities 30 | #include "pr_queue_k.h" // k-element priority queue 31 | 32 | #include // performance evaluation 33 | 34 | //---------------------------------------------------------------------- 35 | // More global variables 36 | // These are active for the life of each call to annkSearch(). They 37 | // are set to save the number of variables that need to be passed 38 | // among the various search procedures. 39 | //---------------------------------------------------------------------- 40 | 41 | extern int ANNkdDim; // dimension of space (static copy) 42 | extern ANNpoint ANNkdQ; // query point (static copy) 43 | extern double ANNkdMaxErr; // max tolerable squared error 44 | extern ANNpointArray ANNkdPts; // the points (static copy) 45 | extern ANNmin_k *ANNkdPointMK; // set of k closest points 46 | extern int ANNptsVisited; // number of points visited 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ext/ANN/kd_split.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_split.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Methods for splitting kd-trees 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_KD_SPLIT_H 26 | #define ANN_KD_SPLIT_H 27 | 28 | #include "kd_tree.h" // kd-tree definitions 29 | 30 | //---------------------------------------------------------------------- 31 | // External entry points 32 | // These are all splitting procedures for kd-trees. 33 | //---------------------------------------------------------------------- 34 | 35 | void kd_split( // standard (optimized) kd-splitter 36 | ANNpointArray pa, // point array (unaltered) 37 | ANNidxArray pidx, // point indices (permuted on return) 38 | const ANNorthRect &bnds, // bounding rectangle for cell 39 | int n, // number of points 40 | int dim, // dimension of space 41 | int &cut_dim, // cutting dimension (returned) 42 | ANNcoord &cut_val, // cutting value (returned) 43 | int &n_lo); // num of points on low side (returned) 44 | 45 | void midpt_split( // midpoint kd-splitter 46 | ANNpointArray pa, // point array (unaltered) 47 | ANNidxArray pidx, // point indices (permuted on return) 48 | const ANNorthRect &bnds, // bounding rectangle for cell 49 | int n, // number of points 50 | int dim, // dimension of space 51 | int &cut_dim, // cutting dimension (returned) 52 | ANNcoord &cut_val, // cutting value (returned) 53 | int &n_lo); // num of points on low side (returned) 54 | 55 | void sl_midpt_split( // sliding midpoint kd-splitter 56 | ANNpointArray pa, // point array (unaltered) 57 | ANNidxArray pidx, // point indices (permuted on return) 58 | const ANNorthRect &bnds, // bounding rectangle for cell 59 | int n, // number of points 60 | int dim, // dimension of space 61 | int &cut_dim, // cutting dimension (returned) 62 | ANNcoord &cut_val, // cutting value (returned) 63 | int &n_lo); // num of points on low side (returned) 64 | 65 | void fair_split( // fair-split kd-splitter 66 | ANNpointArray pa, // point array (unaltered) 67 | ANNidxArray pidx, // point indices (permuted on return) 68 | const ANNorthRect &bnds, // bounding rectangle for cell 69 | int n, // number of points 70 | int dim, // dimension of space 71 | int &cut_dim, // cutting dimension (returned) 72 | ANNcoord &cut_val, // cutting value (returned) 73 | int &n_lo); // num of points on low side (returned) 74 | 75 | void sl_fair_split( // sliding fair-split kd-splitter 76 | ANNpointArray pa, // point array (unaltered) 77 | ANNidxArray pidx, // point indices (permuted on return) 78 | const ANNorthRect &bnds, // bounding rectangle for cell 79 | int n, // number of points 80 | int dim, // dimension of space 81 | int &cut_dim, // cutting dimension (returned) 82 | ANNcoord &cut_val, // cutting value (returned) 83 | int &n_lo); // num of points on low side (returned) 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /ext/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(${tstop_SOURCE_DIR}/ext) 2 | SUBDIRS(ANN geom_dist/wasserstein geom_dist/bottleneck) 3 | -------------------------------------------------------------------------------- /ext/geom_dist/README_bottleneck: -------------------------------------------------------------------------------- 1 | Accompanying paper: M. Kerber, D. Morozov, A. Nigmetov. Geometry Helps To Compare Persistence Diagrams (ALENEX 2016, http://www.geometrie.tugraz.at/nigmetov/geom_dist.pdf) 2 | 3 | Bug reports can be sent to "nigmetov EMAIL SIGN tugraz DOT at". 4 | 5 | # Dependencies 6 | 7 | The program uses the ANN library (http://www.cs.umd.edu/~mount/ANN/), 8 | modified to support deletion of points from k-d trees. 9 | The modified version is contained in "bottleneck/src/ann" and "bottleneck/iclude/ANN" 10 | directories, there is no need to build ANN separately or include ANN's headers. 11 | 12 | Your compiler must support C++11. 13 | 14 | # Usage: 15 | 16 | 1. To use a standalone command-line utility bottleneck_dist: 17 | 18 | bottleneck_dist file1 file2 [relative_error]. 19 | 20 | If relative error is not supplied, the exact distance is computed. 21 | file1 and file2 must contain persistence diagrams in plain text format 22 | (one point per line, empty lines are ignored, comments can be made with #): 23 | 24 | # this is how your input can look like 25 | x_1 y_1 # two real numbers per line 26 | ... 27 | # empty lines or comments are ignored 28 | x_n y_n 29 | 30 | 2. To use from your code: 31 | 32 | #include "bottleneck.h" 33 | 34 | // All classes and functions are in geom_bt namespace 35 | // (including modified ANN's classes). 36 | 37 | std::vector> diagram1, diagram2; 38 | // any container class that supports range-for loops will do. 39 | // A pair represents a single point, 40 | // first component = x-coordinate, 41 | // second component = y-coordinate. 42 | // ... 43 | // load your diagrams into diagram1, diagram2 (off-diagonal points). 44 | // If you data is in plain text format, you can use readDiagramPointSet function: 45 | 46 | if (!geom_bt::readDiagramPointSet("diagram1.txt", diagram1)) { 47 | // something went wrong: function returns true if it successfully read the file 48 | } 49 | 50 | // OK: diagram1.txt was read. 51 | // ... 52 | // to get exact distance: 53 | double btDist = geom_bt::bottleneckDistExact(diagram1, diagram2); 54 | // to get 1% approximation 55 | double btDistApprox = geom_bt::bottleneckDistApprox(diagram1, diagram2, 0.01); 56 | // .............................................................................. 57 | // if diagrams will be used many times, you may want to avoid copying them 58 | // to DiagramPointSet (which is done internally in each call to 59 | bottleneckDistExact/bottleneckDistApprox) and do it yourself once. 60 | // Constructor takes two iterators: 61 | geom_bt::DiagramPointSet ds1(diagram1.begin(), diagram1.end()); 62 | geom_bt::DiagramPointSet ds2(diagram2.begin(), diagram2.end()); 63 | btDist = geom_bt::bottleneckDistExact(ds1, ds2); 64 | btDistApprox = geom_bt::bottleneckDistApprox(ds1, ds2, 0.01); 65 | 66 | Necessary projections (diagonal points) will be added in the bottleneckDistApprox 67 | function. 68 | 69 | See also code in example/bottleneck_dist.cpp. 70 | 71 | # Remarks: 72 | 73 | 1) If bottleneckDistApprox is called with epsilon = 0.0, it will never return. 74 | 2) Empty diagrams are not considered as error. 75 | 3) Modifications made in the ANN code are only valid for 2-dimensional k-d trees. 76 | Do not use the modified ANN files from the project folder anywhere else. 77 | 4) You can switch to non-geometric version by using another typedef in 78 | bottleneck/include/neigb_oracle.h. 79 | 80 | # License 81 | 82 | The program is distributed under Lesser GPL license. 83 | 84 | # Building 85 | 86 | CMakeLists.txt in the root directory can be used to make the library (contained 87 | in bottleneck/ directory) and the command-line utility (in example/ directory) 88 | to compute the distance between two diagrams in txt files. 89 | 90 | On Linux/Mac: 91 | 92 | mdkir build 93 | cd build 94 | cmake .. 95 | make 96 | 97 | On Windows (checked with Visual Studio 2015, Community version) 98 | use cmake-gui to create the solution in build directory and build it with VS. 99 | -------------------------------------------------------------------------------- /ext/geom_dist/README_wasserstein: -------------------------------------------------------------------------------- 1 | This is a program for computing Wasserstein distances between persistence 2 | diagrams using the geometric version of auction algorithm. 3 | 4 | Accompanying paper: M. Kerber, D. Morozov, A. Nigmetov. Geometry Helps To Compare 5 | Persistence Diagrams (ALENEX 2016, http://www.geometrie.tugraz.at/nigmetov/geom_dist.pdf) 6 | Bug reports can be sent to "nigmetov EMAIL SIGN tugraz DOT at". 7 | 8 | Wasserstein distance $W_{q, p}(X, Y)$ between two persistent diagrams is 9 | the minimum over all perfect matchings between $X$ and $Y$ ( $y(x)$ is the point of $Y$ 10 | matched to $x \in X$ ) of the following expression: 11 | $ ( \sum \| x - y(x) \|_p ^ { q } ) ^ { 1 / q} $ 12 | 13 | # Dependencies 14 | 15 | Requires boost 1.58 or higher. 16 | Your compiler must support C++11. 17 | 18 | # Usage: 19 | 20 | To use a standalone command-line utility wasserstein_dist: 21 | 22 | wasserstein_dist file1 file2 [wasserstein degree] [relative error] [internal norm]. 23 | 24 | Parameter wasserstein degree corresponds to $q$, when it tends to infinity, 25 | Wasserstein distance tends to the bottleneck distance. 26 | 27 | Parameter internal_p corresponds to p. 28 | 29 | Default values: 30 | wasserstein_degree = 1.0, 31 | relative_error = 0.01, 32 | internal_p = infinity. 33 | 34 | Valid values: 35 | wasserstein_degree must be in $[1.0, \infinity)$, 36 | relative_error must be positive, 37 | internal_p must be in $[1.0, \infinity]$ (to explicitly set internal_p to $\infinity$, supply inf).By default wasserstein degree is 1.0, relative error is 0.01, internal norm is l_infinity. 38 | 39 | file1 and file2 must contain persistence diagrams in plain text format 40 | (one point per line, empty lines are ignored, comments can be made with #): 41 | 42 | # this is how your input can look like 43 | x_1 y_1 # two real numbers per line 44 | ... 45 | # empty lines or comments are ignored 46 | x_n y_n 47 | 48 | To use from your code: 49 | 50 | #include "wasserstein.h" 51 | 52 | // All classes and functions are in geom_ws namespace 53 | 54 | std::vector> diagram1, diagram2; 55 | // any container class that supports range-for loops will do. 56 | // A pair represents a single point, 57 | // first component = x-coordinate, 58 | // second component = y-coordinate. 59 | // ... 60 | // load your diagrams into diagram1, diagram2 (off-diagonal points). 61 | // You can use function readDiagramPointSet: 62 | geom_ws::readDiagramPointSet("diagram1.txt", diagram1); 63 | geom_ws::readDiagramPointSet("diagram2.txt", diagram1); 64 | // ... 65 | // to get the distance: 66 | double wsDist = geom_ws::wassersteinDist(diagram1, diagram2, q, delta, p); 67 | // q is wasserstein degree, delta is relative error, 68 | // p is the internal norm in Wasserstein distance, defaults to infinity 69 | 70 | Necessary projections (diagonal points) will be added in the wassersteinDist 71 | function. 72 | 73 | See also code in wasserstein/example/wasserstein_dist.cpp. 74 | 75 | # License 76 | 77 | See wasserstein/license.txt 78 | 79 | # Building 80 | 81 | CMakeLists.txt in the root directory can be used to make the library (contained 82 | in wasserstein/src/ directory) and the command-line utility (in wasserstein/example/ directory) 83 | to compute the distance between two diagrams in txt files. 84 | 85 | On Linux/Mac: 86 | 87 | mdkir build 88 | cd build 89 | cmake .. 90 | make 91 | 92 | On Windows (checked with Visual Studio 2015, Community version) 93 | use cmake-gui to create the solution in build directory and build it with VS. 94 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(geom_bottleneck) 2 | cmake_minimum_required(VERSION 2.8.9) 3 | include (GenerateExportHeader) 4 | 5 | # Default to Release 6 | if(NOT CMAKE_BUILD_TYPE) 7 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) 8 | endif(NOT CMAKE_BUILD_TYPE) 9 | 10 | # Add path to ANN header files 11 | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" 12 | "${CMAKE_CURRENT_SOURCE_DIR}/include/ANN") 13 | 14 | set(CXX_FLAGS ${CMAKE_CXX_FLAGS_RELEASE}) 15 | 16 | if(NOT WIN32) 17 | set(CMAKE_CXX_FLAGS "-O3 -DNDEBUG -DBOOST_DISABLE_ASSERTS") 18 | add_definitions(-std=c++11 -fPIC) 19 | endif(NOT WIN32) 20 | 21 | file(GLOB ANN_SRC_FILES src/ann/*.cpp) 22 | 23 | add_library(bottleneck src/bottleneck.cpp src/bound_match.cpp src/neighb_oracle.cpp src/basic_defs.cpp ${ANN_SRC_FILES}) 24 | if (WIN32) 25 | GENERATE_EXPORT_HEADER(bottleneck 26 | BASE_NAME bottleneck 27 | EXPORT_MACRO_NAME bottleneck_EXPORT 28 | EXPORT_FILE_NAME bottleneck_export.h 29 | STATIC_DEFINE bottleneck_BUILT_AS_STATIC) 30 | endif(WIN32) 31 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/include/ANN/kd_fix_rad_search.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_fix_rad_search.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Standard kd-tree fixed-radius kNN search 5 | // Last modified: 05/03/05 (Version 1.1) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 1.1 05/03/05 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_kd_fix_rad_search_H 26 | #define ANN_kd_fix_rad_search_H 27 | 28 | #include "kd_tree.h" // kd-tree declarations 29 | #include "kd_util.h" // kd-tree utilities 30 | #include "pr_queue_k.h" // k-element priority queue 31 | 32 | #include // performance evaluation 33 | 34 | namespace geom_bt { 35 | //---------------------------------------------------------------------- 36 | // Global variables 37 | // These are active for the life of each call to 38 | // annRangeSearch(). They are set to save the number of 39 | // variables that need to be passed among the various search 40 | // procedures. 41 | //---------------------------------------------------------------------- 42 | 43 | extern ANNpoint ANNkdFRQ; // query point (static copy) 44 | 45 | } 46 | #endif -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/include/ANN/kd_pr_search.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_pr_search.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Priority kd-tree search 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_kd_pr_search_H 26 | #define ANN_kd_pr_search_H 27 | 28 | #include "kd_tree.h" // kd-tree declarations 29 | #include "kd_util.h" // kd-tree utilities 30 | #include "pr_queue.h" // priority queue declarations 31 | #include "pr_queue_k.h" // k-element priority queue 32 | 33 | #include // performance evaluation 34 | 35 | namespace geom_bt { 36 | //---------------------------------------------------------------------- 37 | // Global variables 38 | // Active for the life of each call to Appx_Near_Neigh() or 39 | // Appx_k_Near_Neigh(). 40 | //---------------------------------------------------------------------- 41 | 42 | extern double ANNprEps; // the error bound 43 | extern int ANNprDim; // dimension of space 44 | extern ANNpoint ANNprQ; // query point 45 | extern double ANNprMaxErr; // max tolerable squared error 46 | extern ANNpointArray ANNprPts; // the points 47 | extern ANNpr_queue *ANNprBoxPQ; // priority queue for boxes 48 | extern ANNmin_k *ANNprPointMK; // set of k closest points 49 | 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/include/ANN/kd_search.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: kd_search.h 3 | // Programmer: Sunil Arya and David Mount 4 | // Description: Standard kd-tree search 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef ANN_kd_search_H 26 | #define ANN_kd_search_H 27 | 28 | #include "kd_tree.h" // kd-tree declarations 29 | #include "kd_util.h" // kd-tree utilities 30 | #include "pr_queue_k.h" // k-element priority queue 31 | 32 | #include // performance evaluation 33 | 34 | namespace geom_bt { 35 | //---------------------------------------------------------------------- 36 | // More global variables 37 | // These are active for the life of each call to annkSearch(). They 38 | // are set to save the number of variables that need to be passed 39 | // among the various search procedures. 40 | //---------------------------------------------------------------------- 41 | 42 | extern int ANNkdDim; // dimension of space (static copy) 43 | extern ANNpoint ANNkdQ; // query point (static copy) 44 | extern double ANNkdMaxErr; // max tolerable squared error 45 | extern ANNpointArray ANNkdPts; // the points (static copy) 46 | extern ANNmin_k *ANNkdPointMK; // set of k closest points 47 | extern int ANNptsVisited; // number of points visited 48 | 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/include/bound_match.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyrigth 2015, D. Morozov, M. Kerber, A. Nigmetov 3 | 4 | This file is part of GeomBottleneck. 5 | 6 | GeomBottleneck is free software: you can redistribute it and/or modify 7 | it under the terms of the Lesser GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GeomBottleneck is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | Lesser GNU General Public License for more details. 15 | 16 | You should have received a copy of the Lesser GNU General Public License 17 | along with GeomBottleneck. If not, see . 18 | 19 | */ 20 | 21 | #ifndef BOUND_MATCH_H 22 | #define BOUND_MATCH_H 23 | 24 | #include 25 | 26 | #include "basic_defs_bt.h" 27 | #include "neighb_oracle.h" 28 | 29 | 30 | namespace geom_bt { 31 | typedef std::vector Path; 32 | 33 | class Matching { 34 | public: 35 | Matching(const DiagramPointSet& AA, const DiagramPointSet& BB) : A(AA), B(BB) {}; 36 | DiagramPointSet getExposedVertices(bool forA = true) const ; 37 | bool isExposed(const DiagramPoint& p) const; 38 | void getAllAdjacentVertices(const DiagramPointSet& setIn, DiagramPointSet& setOut, bool forA = true) const; 39 | void increase(const Path& augmentingPath); 40 | void checkAugPath(const Path& augPath) const; 41 | bool getMatchedVertex(const DiagramPoint& p, DiagramPoint& result) const; 42 | bool isPerfect() const; 43 | void trimMatching(const double newThreshold); 44 | friend std::ostream& operator<<(std::ostream& output, const Matching& m); 45 | private: 46 | DiagramPointSet A; 47 | DiagramPointSet B; 48 | std::unordered_map AToB, BToA; 49 | void matchVertices(const DiagramPoint& pA, const DiagramPoint& pB); 50 | void sanityCheck() const; 51 | }; 52 | 53 | 54 | 55 | class BoundMatchOracle { 56 | public: 57 | BoundMatchOracle(DiagramPointSet psA, DiagramPointSet psB, double dEps, bool useRS = true); 58 | bool isMatchLess(double r); 59 | void setInnerOracle(NeighbOracleAbstract* innerOracle) { neighbOracle = innerOracle; } 60 | bool buildMatchingForThreshold(const double r); 61 | ~BoundMatchOracle(); 62 | private: 63 | DiagramPointSet A, B; 64 | Matching M; 65 | void printLayerGraph(void); 66 | void buildLayerGraph(double r); 67 | void buildLayerOracles(double r); 68 | bool buildAugmentingPath(const DiagramPoint startVertex, Path& result); 69 | void removeFromLayer(const DiagramPoint& p, const int layerIdx); 70 | NeighbOracleAbstract* neighbOracle; 71 | bool augPathExist; 72 | std::vector layerGraph; 73 | std::vector layerOracles; 74 | double distEpsilon; 75 | bool useRangeSearch; 76 | double prevQueryValue; 77 | }; 78 | 79 | } 80 | #endif 81 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/include/def_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyrigth 2015, D. Morozov, M. Kerber, A. Nigmetov 3 | 4 | This file is part of GeomBottleneck. 5 | 6 | GeomBottleneck is free software: you can redistribute it and/or modify 7 | it under the terms of the Lesser GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GeomBottleneck is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | Lesser GNU General Public License for more details. 15 | 16 | You should have received a copy of the Lesser GNU General Public License 17 | along with GeomBottleneck. If not, see . 18 | 19 | */ 20 | 21 | #ifndef DEF_DEBUG_H 22 | #define DEF_DEBUG_H 23 | 24 | //#define DEBUG_BOUND_MATCH 25 | //#define DEBUG_NEIGHBOUR_ORACLE 26 | //#define DEBUG_MATCHING 27 | //#define DEBUG_AUCTION 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/include/neighb_oracle.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyrigth 2015, D. Morozov, M. Kerber, A. Nigmetov 3 | 4 | This file is part of GeomBottleneck. 5 | 6 | GeomBottleneck is free software: you can redistribute it and/or modify 7 | it under the terms of the Lesser GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GeomBottleneck is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | Lesser GNU General Public License for more details. 15 | 16 | You should have received a copy of the Lesser GNU General Public License 17 | along with GeomBottleneck. If not, see . 18 | 19 | */ 20 | 21 | #ifndef NEIGHB_ORACLE_H 22 | #define NEIGHB_ORACLE_H 23 | 24 | #include 25 | #include "basic_defs_bt.h" 26 | #include 27 | 28 | namespace geom_bt { 29 | class NeighbOracleAbstract{ 30 | public: 31 | virtual void deletePoint(const DiagramPoint& p) = 0; 32 | virtual void rebuild(const DiagramPointSet& S, double rr) = 0; 33 | // return true, if r-neighbour of q exists in pointSet, 34 | // false otherwise. 35 | // the neighbour is returned in result 36 | virtual bool getNeighbour(const DiagramPoint& q, DiagramPoint& result) const = 0; 37 | virtual void getAllNeighbours(const DiagramPoint& q, std::vector& result) = 0; 38 | virtual ~NeighbOracleAbstract() {}; 39 | protected: 40 | double r; 41 | double distEpsilon; 42 | }; 43 | 44 | class NeighbOracleSimple : public NeighbOracleAbstract 45 | { 46 | public: 47 | NeighbOracleSimple(); 48 | NeighbOracleSimple(const DiagramPointSet& S, const double rr, const double dEps); 49 | void deletePoint(const DiagramPoint& p); 50 | void rebuild(const DiagramPointSet& S, const double rr); 51 | bool getNeighbour(const DiagramPoint& q, DiagramPoint& result) const; 52 | void getAllNeighbours(const DiagramPoint& q, std::vector& result); 53 | ~NeighbOracleSimple() {}; 54 | private: 55 | DiagramPointSet pointSet; 56 | }; 57 | 58 | class NeighbOracleAnn : public NeighbOracleAbstract 59 | { 60 | public: 61 | NeighbOracleAnn(const DiagramPointSet& S, const double rr, const double dEps); 62 | void deletePoint(const DiagramPoint& p); 63 | void rebuild(const DiagramPointSet& S, const double rr); 64 | bool getNeighbour(const DiagramPoint& q, DiagramPoint& result) const; 65 | void getAllNeighbours(const DiagramPoint& q, std::vector& result); 66 | ~NeighbOracleAnn(); 67 | //private: 68 | //DiagramPointSet originalPointSet; 69 | std::vector allPoints; 70 | DiagramPointSet diagonalPoints; 71 | std::unordered_map pointIdxLookup; 72 | // ann-stuff 73 | static constexpr double annEpsilon {0}; 74 | static const int annK {1}; 75 | static const int annDim{2}; 76 | ANNpointArray annPoints; 77 | ANNkd_tree* kdTree; 78 | ANNidxArray annNeigbIndices; 79 | ANNpoint annQueryPoint; 80 | // to use in getAllNeighbours 81 | ANNpoint lo; 82 | ANNpoint hi; 83 | ANNidxArray annIndices; 84 | ANNdistArray annDistances; 85 | }; 86 | 87 | //typedef NeighbOracleSimple NeighbOracle; 88 | typedef NeighbOracleAnn NeighbOracle; 89 | 90 | } 91 | #endif 92 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/lib/dummy: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/src/ann/bd_fix_rad_search.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: bd_fix_rad_search.cpp 3 | // Programmer: David Mount 4 | // Description: Standard bd-tree search 5 | // Last modified: 05/03/05 (Version 1.1) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 1.1 05/03/05 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #include "bd_tree.h" // bd-tree declarations 26 | #include "kd_fix_rad_search.h" // kd-tree FR search declarations 27 | 28 | namespace geom_bt { 29 | 30 | //---------------------------------------------------------------------- 31 | // Approximate searching for bd-trees. 32 | // See the file kd_FR_search.cpp for general information on the 33 | // approximate nearest neighbor search algorithm. Here we 34 | // include the extensions for shrinking nodes. 35 | //---------------------------------------------------------------------- 36 | 37 | //---------------------------------------------------------------------- 38 | // bd_shrink::ann_FR_search - search a shrinking node 39 | //---------------------------------------------------------------------- 40 | 41 | void ANNbd_shrink::ann_FR_search(ANNdist box_dist) 42 | { 43 | // check dist calc term cond. 44 | if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; 45 | 46 | ANNdist inner_dist = 0; // distance to inner box 47 | for (int i = 0; i < n_bnds; i++) { // is query point in the box? 48 | if (bnds[i].out(ANNkdFRQ)) { // outside this bounding side? 49 | // add to inner distance 50 | inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdFRQ)); 51 | } 52 | } 53 | if (inner_dist <= box_dist) { // if inner box is closer 54 | child[ANN_IN]->ann_FR_search(inner_dist);// search inner child first 55 | child[ANN_OUT]->ann_FR_search(box_dist);// ...then outer child 56 | } 57 | else { // if outer box is closer 58 | child[ANN_OUT]->ann_FR_search(box_dist);// search outer child first 59 | child[ANN_IN]->ann_FR_search(inner_dist);// ...then outer child 60 | } 61 | ANN_FLOP(3*n_bnds) // increment floating ops 62 | ANN_SHR(1) // one more shrinking node 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/src/ann/bd_pr_search.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: bd_pr_search.cpp 3 | // Programmer: David Mount 4 | // Description: Priority search for bd-trees 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | //History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #include "bd_tree.h" // bd-tree declarations 26 | #include "kd_pr_search.h" // kd priority search declarations 27 | 28 | 29 | namespace geom_bt { 30 | 31 | //---------------------------------------------------------------------- 32 | // Approximate priority searching for bd-trees. 33 | // See the file kd_pr_search.cc for general information on the 34 | // approximate nearest neighbor priority search algorithm. Here 35 | // we include the extensions for shrinking nodes. 36 | //---------------------------------------------------------------------- 37 | 38 | //---------------------------------------------------------------------- 39 | // bd_shrink::ann_search - search a shrinking node 40 | //---------------------------------------------------------------------- 41 | 42 | void ANNbd_shrink::ann_pri_search(ANNdist box_dist) 43 | { 44 | ANNdist inner_dist = 0; // distance to inner box 45 | for (int i = 0; i < n_bnds; i++) { // is query point in the box? 46 | if (bnds[i].out(ANNprQ)) { // outside this bounding side? 47 | // add to inner distance 48 | inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNprQ)); 49 | } 50 | } 51 | if (inner_dist <= box_dist) { // if inner box is closer 52 | if (child[ANN_OUT] != KD_TRIVIAL) // enqueue outer if not trivial 53 | ANNprBoxPQ->insert(box_dist,child[ANN_OUT]); 54 | // continue with inner child 55 | child[ANN_IN]->ann_pri_search(inner_dist); 56 | } 57 | else { // if outer box is closer 58 | if (child[ANN_IN] != KD_TRIVIAL) // enqueue inner if not trivial 59 | ANNprBoxPQ->insert(inner_dist,child[ANN_IN]); 60 | // continue with outer child 61 | child[ANN_OUT]->ann_pri_search(box_dist); 62 | } 63 | ANN_FLOP(3*n_bnds) // increment floating ops 64 | ANN_SHR(1) // one more shrinking node 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ext/geom_dist/bottleneck/src/ann/bd_search.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------- 2 | // File: bd_search.cpp 3 | // Programmer: David Mount 4 | // Description: Standard bd-tree search 5 | // Last modified: 01/04/05 (Version 1.0) 6 | //---------------------------------------------------------------------- 7 | // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and 8 | // David Mount. All Rights Reserved. 9 | // 10 | // This software and related documentation is part of the Approximate 11 | // Nearest Neighbor Library (ANN). This software is provided under 12 | // the provisions of the Lesser GNU Public License (LGPL). See the 13 | // file ../ReadMe.txt for further information. 14 | // 15 | // The University of Maryland (U.M.) and the authors make no 16 | // representations about the suitability or fitness of this software for 17 | // any purpose. It is provided "as is" without express or implied 18 | // warranty. 19 | //---------------------------------------------------------------------- 20 | // History: 21 | // Revision 0.1 03/04/98 22 | // Initial release 23 | //---------------------------------------------------------------------- 24 | 25 | #include "bd_tree.h" // bd-tree declarations 26 | #include "kd_search.h" // kd-tree search declarations 27 | 28 | namespace geom_bt { 29 | 30 | //---------------------------------------------------------------------- 31 | // Approximate searching for bd-trees. 32 | // See the file kd_search.cpp for general information on the 33 | // approximate nearest neighbor search algorithm. Here we 34 | // include the extensions for shrinking nodes. 35 | //---------------------------------------------------------------------- 36 | 37 | //---------------------------------------------------------------------- 38 | // bd_shrink::ann_search - search a shrinking node 39 | //---------------------------------------------------------------------- 40 | 41 | void ANNbd_shrink::ann_search(ANNdist box_dist) 42 | { 43 | // check dist calc term cond. 44 | if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; 45 | 46 | ANNdist inner_dist = 0; // distance to inner box 47 | for (int i = 0; i < n_bnds; i++) { // is query point in the box? 48 | if (bnds[i].out(ANNkdQ)) { // outside this bounding side? 49 | // add to inner distance 50 | inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdQ)); 51 | } 52 | } 53 | if (inner_dist <= box_dist) { // if inner box is closer 54 | child[ANN_IN]->ann_search(inner_dist); // search inner child first 55 | child[ANN_OUT]->ann_search(box_dist); // ...then outer child 56 | } 57 | else { // if outer box is closer 58 | child[ANN_OUT]->ann_search(box_dist); // search outer child first 59 | child[ANN_IN]->ann_search(inner_dist); // ...then outer child 60 | } 61 | ANN_FLOP(3*n_bnds) // increment floating ops 62 | ANN_SHR(1) // one more shrinking node 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ext/geom_dist/wasserstein/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project (wasserstein) 2 | cmake_minimum_required (VERSION 2.8.9) 3 | include (GenerateExportHeader) 4 | 5 | # Default to Release 6 | 7 | if (NOT CMAKE_BUILD_TYPE) 8 | set (CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) 9 | endif (NOT CMAKE_BUILD_TYPE) 10 | 11 | # Boost 12 | find_package (Boost) 13 | include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include 14 | SYSTEM ${Boost_INCLUDE_DIR}) 15 | 16 | if(NOT WIN32) 17 | set(CMAKE_CXX_FLAGS "-O3 -DNDEBUG -DBOOST_DISABLE_ASSERTS") 18 | add_definitions(-std=c++11 -fPIC) 19 | endif(NOT WIN32) 20 | 21 | file(GLOB WS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) 22 | 23 | add_library(wasserstein ${WS_SOURCES}) 24 | 25 | if (WIN32) 26 | GENERATE_EXPORT_HEADER(wasserstein 27 | BASE_NAME wasserstein 28 | EXPORT_MACRO_NAME wasserstein_EXPORT 29 | EXPORT_FILE_NAME wasserstein_export.h 30 | STATIC_DEFINE wasserstein_BUILT_AS_STATIC) 31 | endif(WIN32) 32 | 33 | add_executable(wasserstein_dist ${CMAKE_CURRENT_SOURCE_DIR}/example/wasserstein_dist.cpp) 34 | target_link_libraries(wasserstein_dist PUBLIC wasserstein) 35 | -------------------------------------------------------------------------------- /ext/geom_dist/wasserstein/include/def_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2015, M. Kerber, D. Morozov, A. Nigmetov 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | 16 | You are under no obligation whatsoever to provide any bug fixes, patches, or 17 | upgrades to the features, functionality or performance of the source code 18 | (Enhancements) to anyone; however, if you choose to make your Enhancements 19 | available either publicly, or directly to copyright holder, 20 | without imposing a separate written license agreement for such Enhancements, 21 | then you hereby grant the following license: a non-exclusive, royalty-free 22 | perpetual license to install, use, modify, prepare derivative works, incorporate 23 | into other computer software, distribute, and sublicense such enhancements or 24 | derivative works thereof, in binary and source code form. 25 | 26 | */ 27 | 28 | #ifndef DEF_DEBUG_H 29 | #define DEF_DEBUG_H 30 | 31 | //#define DEBUG_BOUND_MATCH 32 | //#define DEBUG_NEIGHBOUR_ORACLE 33 | //#define DEBUG_MATCHING 34 | //#define DEBUG_AUCTION 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /ext/geom_dist/wasserstein/include/dnn/local/search-functors.h: -------------------------------------------------------------------------------- 1 | #ifndef DNN_LOCAL_SEARCH_FUNCTORS_H 2 | #define DNN_LOCAL_SEARCH_FUNCTORS_H 3 | 4 | #include 5 | 6 | namespace dnn 7 | { 8 | 9 | template 10 | struct HandleDistance 11 | { 12 | typedef typename NN::PointHandle PointHandle; 13 | typedef typename NN::DistanceType DistanceType; 14 | typedef typename NN::HDContainer HDContainer; 15 | 16 | HandleDistance() {} 17 | HandleDistance(PointHandle pp, DistanceType dd): 18 | p(pp), d(dd) {} 19 | bool operator<(const HandleDistance& other) const { return d < other.d; } 20 | 21 | PointHandle p; 22 | DistanceType d; 23 | }; 24 | 25 | template 26 | struct NNRecord 27 | { 28 | typedef typename HandleDistance::PointHandle PointHandle; 29 | typedef typename HandleDistance::DistanceType DistanceType; 30 | 31 | NNRecord() { result.d = std::numeric_limits::infinity(); } 32 | DistanceType operator()(PointHandle p, DistanceType d) { if (d < result.d) { result.p = p; result.d = d; } return result.d; } 33 | HandleDistance result; 34 | }; 35 | 36 | template 37 | struct rNNRecord 38 | { 39 | typedef typename HandleDistance::PointHandle PointHandle; 40 | typedef typename HandleDistance::DistanceType DistanceType; 41 | typedef typename HandleDistance::HDContainer HDContainer; 42 | 43 | rNNRecord(DistanceType r_): r(r_) {} 44 | DistanceType operator()(PointHandle p, DistanceType d) 45 | { 46 | if (d <= r) 47 | result.push_back(HandleDistance(p,d)); 48 | return r; 49 | } 50 | 51 | DistanceType r; 52 | HDContainer result; 53 | }; 54 | 55 | template 56 | struct kNNRecord 57 | { 58 | typedef typename HandleDistance::PointHandle PointHandle; 59 | typedef typename HandleDistance::DistanceType DistanceType; 60 | typedef typename HandleDistance::HDContainer HDContainer; 61 | 62 | kNNRecord(unsigned k_): k(k_) {} 63 | DistanceType operator()(PointHandle p, DistanceType d) 64 | { 65 | if (result.size() < k) 66 | { 67 | result.push_back(HandleDistance(p,d)); 68 | boost::push_heap(result); 69 | if (result.size() < k) 70 | return std::numeric_limits::infinity(); 71 | } else if (d < result[0].d) 72 | { 73 | boost::pop_heap(result); 74 | result.back() = HandleDistance(p,d); 75 | boost::push_heap(result); 76 | } 77 | if ( result.size() > 1 ) { 78 | assert( result[0].d >= result[1].d ); 79 | } 80 | return result[0].d; 81 | } 82 | 83 | unsigned k; 84 | HDContainer result; 85 | }; 86 | 87 | } 88 | 89 | #endif // DNN_LOCAL_SEARCH_FUNCTORS_H 90 | -------------------------------------------------------------------------------- /ext/geom_dist/wasserstein/include/dnn/parallel/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef PARALLEL_UTILS_H 2 | #define PARALLEL_UTILS_H 3 | 4 | #include "../utils.h" 5 | 6 | namespace dnn 7 | { 8 | // Assumes rng is synchronized across ranks 9 | template 10 | void shuffle(mpi::communicator& world, DataVector& data, RNGType& rng, const SwapFunctor& swap, DataVector empty = DataVector()); 11 | 12 | template 13 | void shuffle(mpi::communicator& world, DataVector& data, RNGType& rng) 14 | { 15 | typedef decltype(data[0]) T; 16 | shuffle(world, data, rng, [](T& x, T& y) { std::swap(x,y); }); 17 | } 18 | } 19 | 20 | template 21 | void 22 | dnn::shuffle(mpi::communicator& world, DataVector& data, RNGType& rng, const SwapFunctor& swap, DataVector empty) 23 | { 24 | // This is not a perfect shuffle: it dishes out data in chunks of 1/size. 25 | // (It can be interpreted as generating a bistochastic matrix by taking the 26 | // sum of size random permutation matrices.) Hopefully, it works for our purposes. 27 | 28 | typedef typename RNGType::result_type RNGResult; 29 | 30 | int size = world.size(); 31 | int rank = world.rank(); 32 | 33 | // Generate local seeds 34 | boost::uniform_int uniform; 35 | RNGResult seed; 36 | for (size_t i = 0; i < size; ++i) 37 | { 38 | RNGResult v = uniform(rng); 39 | if (i == rank) 40 | seed = v; 41 | } 42 | RNGType local_rng(seed); 43 | 44 | // Shuffle local data 45 | dnn::random_shuffle(data.begin(), data.end(), local_rng, swap); 46 | 47 | // Decide how much of our data goes to i-th processor 48 | std::vector out_counts(size); 49 | std::vector ranks(boost::counting_iterator(0), 50 | boost::counting_iterator(size)); 51 | for (size_t i = 0; i < size; ++i) 52 | { 53 | dnn::random_shuffle(ranks.begin(), ranks.end(), rng); 54 | ++out_counts[ranks[rank]]; 55 | } 56 | 57 | // Fill the outgoing array 58 | size_t total = 0; 59 | std::vector< DataVector > outgoing(size, empty); 60 | for (size_t i = 0; i < size; ++i) 61 | { 62 | size_t count = data.size()*out_counts[i]/size; 63 | if (total + count > data.size()) 64 | count = data.size() - total; 65 | 66 | outgoing[i].reserve(count); 67 | for (size_t j = total; j < total + count; ++j) 68 | outgoing[i].push_back(data[j]); 69 | 70 | total += count; 71 | } 72 | 73 | boost::uniform_int uniform_outgoing(0,size-1); // in range [0,size-1] 74 | while(total < data.size()) // send leftover to random processes 75 | { 76 | outgoing[uniform_outgoing(local_rng)].push_back(data[total]); 77 | ++total; 78 | } 79 | data.clear(); 80 | 81 | // Exchange the data 82 | std::vector< DataVector > incoming(size, empty); 83 | mpi::all_to_all(world, outgoing, incoming); 84 | outgoing.clear(); 85 | 86 | // Assemble our data 87 | for(const DataVector& vec : incoming) 88 | for (size_t i = 0; i < vec.size(); ++i) 89 | data.push_back(vec[i]); 90 | dnn::random_shuffle(data.begin(), data.end(), local_rng, swap); 91 | // XXX: the final shuffle is irrelevant for our purposes. But it's also cheap. 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /ext/geom_dist/wasserstein/include/dnn/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef DNN_UTILS_H 2 | #define DNN_UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace dnn 9 | { 10 | 11 | template 12 | struct has_coordinates 13 | { 14 | template ().coordinate(std::declval()...) )> 15 | static std::true_type test(int); 16 | 17 | template 18 | static std::false_type test(...); 19 | 20 | static constexpr bool value = decltype(test(0))::value; 21 | }; 22 | 23 | template 24 | void random_shuffle(RandomIt first, RandomIt last, UniformRandomNumberGenerator& g, const SwapFunctor& swap) 25 | { 26 | size_t n = last - first; 27 | boost::uniform_int uniform(0,n); 28 | for (size_t i = n-1; i > 0; --i) 29 | swap(first[i], first[uniform(g,i+1)]); // picks a random number in [0,i] range 30 | } 31 | 32 | template 33 | void random_shuffle(RandomIt first, RandomIt last, UniformRandomNumberGenerator& g) 34 | { 35 | typedef decltype(*first) T; 36 | random_shuffle(first, last, g, [](T& x, T& y) { std::swap(x,y); }); 37 | } 38 | 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /ext/geom_dist/wasserstein/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, M. Kerber, D. Morozov, A. Nigmetov 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | 14 | You are under no obligation whatsoever to provide any bug fixes, patches, or 15 | upgrades to the features, functionality or performance of the source code 16 | (Enhancements) to anyone; however, if you choose to make your Enhancements 17 | available either publicly, or directly to copyright holder, 18 | without imposing a separate written license agreement for such Enhancements, 19 | then you hereby grant the following license: a non-exclusive, royalty-free 20 | perpetual license to install, use, modify, prepare derivative works, incorporate 21 | into other computer software, distribute, and sublicense such enhancements or 22 | derivative works thereof, in binary and source code form. 23 | -------------------------------------------------------------------------------- /geometry/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${tstop_SOURCE_DIR}/geometry ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}) 2 | file(GLOB geometry_sources ${tstop_SOURCE_DIR}/geometry/*.cpp ${tstop_SOURCE_DIR}/geometry/*.h) 3 | 4 | add_library(geometry SHARED ${geometry_sources}) 5 | -------------------------------------------------------------------------------- /geometry/covertree.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef COVERTREE_H 19 | #define COVERTREE_H 20 | 21 | #include "point_incs.h" 22 | #include 23 | 24 | class CoverTreeNode { 25 | public: 26 | CoverTreeNode(CoverTreeNode* _parent, int _i, int _l); 27 | CoverTreeNode(int _i, int _l); 28 | ~CoverTreeNode(); 29 | 30 | bool insert_child(CoverTreeNode* _node) { children.push_back(_node); } 31 | int num_children() { return children.size(); } 32 | CoverTreeNode* get_parent() { return parent; } 33 | std::vector get_children(); 34 | 35 | int idx() { return i; } 36 | int level() { return l; } 37 | 38 | bool is_root() { return !has_parent; } 39 | bool is_leaf() { return children.size() == 0; } 40 | 41 | bool fully_covers(const SparseVector & _pt, const SparsePoints & _points, double _scale); 42 | 43 | void get_unique_nodes(std::vector* nodes, std::set* unique_ids); 44 | void get_all_child_nodes(std::vector* nodes); 45 | 46 | void populate_parent_radii(std::vector* node_radii, std::vector* parent_radii, const SparsePoints & _points, double _scale); 47 | 48 | bool create_and_insert_node(int _i, int _l, int _pi); 49 | CoverTreeNode* get_self_node(int _l); 50 | 51 | private: 52 | int i, l; 53 | bool has_parent; 54 | CoverTreeNode* parent; 55 | std::vector children; 56 | }; 57 | 58 | class CoverTree { 59 | public: 60 | CoverTree(const SparsePoints & _points, double _scale=2); 61 | CoverTree(const SparsePoints & _points, std::vector _levels, std::vector _parents, double _scale=2); 62 | ~CoverTree(); 63 | 64 | void build_tree(); 65 | int insert_point(int _i); 66 | 67 | double distance_to_set(int _q, const std::vector & _nodes); 68 | bool insert_point(int _q, const std::vector & _coverSet, int _l, int & inserted_level); 69 | 70 | void check_invariants(); 71 | 72 | double parent_radius(int _i) { return parent_radii[_i]; } 73 | 74 | std::set ball_query(SparseVector _pt, double _radius); 75 | 76 | private: 77 | SparsePoints points; 78 | double scale; 79 | 80 | SparseVector center; 81 | double diameter_ub; 82 | 83 | int root_level; 84 | 85 | bool is_constructed; 86 | CoverTreeNode* root_node; 87 | std::vector parent_radii; 88 | 89 | std::vector fps(); 90 | 91 | bool debug; 92 | }; 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /python/persistence/ActivitySegments.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import time 18 | import sys 19 | import json 20 | import csv 21 | import itertools 22 | import argparse 23 | from Datatypes.Configuration import get_filename 24 | from Datatypes.Segments import Segments,Segment 25 | import os 26 | class ActivitySegments(Segments): 27 | def __init__(self, config) : 28 | super(self.__class__, self).__init__(config) 29 | if isinstance(self.config.data_file, list) : 30 | self.config.data_file = self.config.data_file[0] 31 | with open(self.config.data_file, 'r') as data_file : 32 | data_reader = csv.reader(data_file, delimiter=',') 33 | full_data = [line for line in data_reader] 34 | if self.config.label_index == None : 35 | self.config.label_index = 4 36 | label_set = set([d[self.config.label_index] for d in full_data]) 37 | if self.config.window_size == -1 : 38 | self.config.window_size = self.config.segment_size 39 | self.segments = [] 40 | print config 41 | for segment_start in range(0, len(full_data) - self.config.segment_size + 1, self.config.segment_stride) : 42 | segment_end = segment_start + self.config.segment_size 43 | windows = [] 44 | # if the data_index has more than one entry, interleave the results. 45 | # e.g. if data_index is [1,2] it's [(x_0, label), (y_0, label), (x_1, label), (y_1, label)...] 46 | for window_start in range(segment_start, segment_end - self.config.window_size + 1, self.config.window_stride): 47 | window_end = window_start + self.config.window_size 48 | windows.append(list(itertools.chain(*itertools.izip(*[[float(d[i]) for d in full_data[window_start:window_end]] \ 49 | for i in self.config.data_index])))) 50 | 51 | labels = [d[self.config.label_index] for d in full_data[segment_start:segment_end]] 52 | label_dict = dict([(str(l), len([d for d in labels if d == l])) for l in list(set(labels))]) 53 | segment = Segment(windows=windows, 54 | segment_start=segment_start, 55 | segment_size=self.config.segment_size, 56 | window_stride=self.config.window_stride, 57 | window_size=self.config.window_size, 58 | labels=label_dict, 59 | filename=self.config.data_file, 60 | data_index = self.config.data_index, 61 | label_index = self.config.label_index) 62 | self.segments.append(segment) 63 | 64 | @staticmethod 65 | def get_segment_filename(config, gz=True): 66 | fields = ['data_file', 'data_index', 'segment_size', 'segment_stride', 'window_size', 'window_stride'] 67 | return get_filename(config, fields, 'ActivitySegments', gz) 68 | 69 | -------------------------------------------------------------------------------- /python/persistence/AverageKernel.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | import sys 19 | import numpy 20 | import math 21 | import itertools 22 | import argparse 23 | import copy 24 | 25 | from Datatypes.Configuration import get_filename 26 | from Datatypes.Kernel import Kernel 27 | from Datatypes.JSONObject import load_data, save_data 28 | 29 | def AverageKernel(kernels, weights=None) : 30 | config = copy.copy(kernels[0].config) 31 | config.data_index = [kernel.config.data_index for kernel in kernels] 32 | config.status = 'AverageKernel' 33 | segment_info = copy.copy(kernels[0].segment_info) 34 | nkernels = len(kernels) 35 | kernel_dimension = len(kernels[0].segment_info) 36 | if weights == None : 37 | weights = [1] * kernel_dimension 38 | kernel_matrix = [[numpy.average([k.kernel_matrix[i][j] for k in kernels]) for i in range(kernel_dimension)] for j in range(kernel_dimension)] 39 | return Kernel(config, kernel_matrix, segment_info) 40 | 41 | if __name__ == "__main__" : 42 | parser = argparse.ArgumentParser(description="Tool to take multiple Kernels and average them") 43 | parser.add_argument("--infile", "-i", nargs="+") 44 | parser.add_argument("--outfile", "-o") 45 | parser.add_argument("--ratio", "-r", type=float, default=0.5) 46 | parser.add_argument("--pool", "-p") 47 | 48 | args = parser.parse_args(sys.argv[1:]) 49 | kernels_json = [load_data(infile, 'kernel', None, None, sys.argv[0]+": ") for infile in args.infile] 50 | kernels = [Kernel.fromJSONDict(kernel_json) for kernel_json in kernels_json] 51 | 52 | if len(kernels) == 2 : 53 | weights = [args.ratio, 1.0 - args.ratio] 54 | else : 55 | weights = None 56 | average_kernel = AverageKernel(kernels, weights) 57 | 58 | if args.outfile == None : 59 | args.outfile = get_filename(average_kernel.config, 60 | ['max_simplices', 'persistence_epsilon', 61 | 'segment_filename', 'segment_stride', 'segment_size', 62 | 'window_size', 'window_stride', 63 | 'kernel_scale', 'kernel_gamma', 'invariant_epsilon', 64 | 'data_file', 'data_index', 'label_index', 'persistence_degree', 65 | 'data_type', 'post_process', 'post_process_arg'], "AverageKernel") 66 | print "Writing %s" % (args.outfile,) 67 | save_data(args.outfile, average_kernel.toJSONDict()) 68 | -------------------------------------------------------------------------------- /python/persistence/BirdSoundsSegments.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | import time 19 | import sys 20 | import json 21 | import csv 22 | import itertools 23 | import argparse 24 | 25 | from Datatypes.Segments import Segments, Segment 26 | from Datatypes.Configuration import get_filename 27 | 28 | class BirdSoundsSegments(Segments): 29 | """ 30 | Segment class created for parsing mfcc files generated from the audio files at http://www.xeno-canto.org 31 | File paths supply our category labels, using the immediate parent of the mfcc file 32 | e.g. if config.data_file is [ 'data/new_bird_sounds/Colibri-thalassinus/0082.mfcc', 33 | 'data/new_bird_sounds/Cyanocorax-yncas/0066.mfcc' ] 34 | then there are two labels, 'Colibri-thalassinus' and 'Cyanocorax-yncas' 35 | The data format of the mfcc files are simply one floating point number per line, 36 | which are then translated to segments and windows. 37 | """ 38 | def __init__(self, config) : 39 | super(self.__class__, self).__init__(config) 40 | self.config.label_index = None 41 | self.config.data_index = 0 42 | prefix = os.path.commonprefix([os.path.abspath(f) for f in self.config.data_file]) 43 | self.segments = [] 44 | for f in self.config.data_file : 45 | p = os.path.abspath(f)[len(prefix):] 46 | (label, filename) = p.split('/') 47 | with open(f,'r') as data_file : 48 | data = [float(line.strip()) for line in data_file] 49 | for segment_start in range(0, len(data) - self.config.segment_size + 1, self.config.segment_stride) : 50 | segment_end = segment_start + self.config.segment_size 51 | windows = [] 52 | for window_start in range(segment_start, segment_end - self.config.window_size + 1, self.config.window_stride): 53 | window_end = window_start + self.config.window_size 54 | windows.append(data[window_start:window_end]) 55 | labels = dict([(label,self.config.segment_size)]) 56 | self.segments.append(Segment(windows = windows, 57 | segment_start = segment_start, 58 | segment_size = self.config.segment_size, 59 | window_stride = self.config.window_stride, 60 | window_size = self.config.window_size, 61 | labels = labels, 62 | filename = p, 63 | data_index = self.config.data_index, 64 | label_index = self.config.label_index)) 65 | # Strip out trailing '/' 66 | self.config.data_file = prefix[0:-1] 67 | 68 | @staticmethod 69 | def get_segment_filename(config, gz=True): 70 | fields = ['data_file', 'data_index', 'segment_size', 'segment_stride', 'window_size', 'window_stride'] 71 | return get_filename(config, fields, 'BirdSoundsSegments', gz) 72 | 73 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/Distances.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | 19 | from persistence.Datatypes.JSONObject import JSONObject, cond_get, cond_get_obj_list 20 | from persistence.Datatypes.Configuration import Configuration, get_filename 21 | from persistence.Datatypes.Segments import SegmentInfo 22 | 23 | class Distance(JSONObject) : 24 | fields = ['min', 25 | 'mean', 26 | 'max', 27 | 'std'] 28 | def __init__(self, min=None, mean=None, max=None, std=None) : 29 | self.min = min 30 | self.max = max 31 | self.mean = mean 32 | self.std = std 33 | 34 | @classmethod 35 | def fromJSONDict(cls, json): 36 | return cls(cond_get(json,'min'), 37 | cond_get(json,'mean'), 38 | cond_get(json,'max'), 39 | cond_get(json,'std')) 40 | 41 | 42 | class Distances(JSONObject) : 43 | fields = ['config', 44 | 'distances', 45 | 'segment_info'] 46 | def __init__(self, config, distances=None, segment_info=None): 47 | self.config = config 48 | self.distances = distances 49 | self.segment_info = segment_info 50 | 51 | @classmethod 52 | def fromJSONDict(cls, json): 53 | return cls(Configuration.fromJSONDict(json['config']), 54 | [[Distance.fromJSONDict(d) for d in row] for row in json['distances']], 55 | cond_get_obj_list(json, 'segment_info', SegmentInfo)) 56 | 57 | @staticmethod 58 | def get_distances_filename(config, gz=True): 59 | fields = ['data_file', 'data_index', 'segment_size', 60 | 'segment_stride', 'window_size', 'window_stride', 61 | 'max_simplices', 'persistence_epsilon'] 62 | if config.post_process != None : 63 | fields.extend(['post_process', 'post_process_arg']) 64 | 65 | return get_filename(config, fields, "Distances", gz) 66 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/Features.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | 19 | from persistence.Datatypes.JSONObject import JSONObject, cond_get, cond_get_obj_list 20 | from persistence.Datatypes.Configuration import Configuration, get_filename 21 | from persistence.Datatypes.Segments import SegmentInfo 22 | 23 | class Features(JSONObject) : 24 | fields = ['config', 25 | 'features', 26 | 'segment_info'] 27 | def __init__(self, config, features=None, segment_info=None): 28 | self.config = config 29 | self.features = features 30 | self.segment_info = segment_info 31 | 32 | @classmethod 33 | def fromJSONDict(cls, json): 34 | return cls(Configuration.fromJSONDict(json['config']), 35 | [f for f in json['features']], 36 | cond_get_obj_list(json, 'segment_info', SegmentInfo)) 37 | 38 | @staticmethod 39 | def get_features_filename(config, gz=True): 40 | fields = ['data_file', 'data_index', 'segment_size', 41 | 'segment_stride', 'window_size', 'window_stride', 42 | 'max_simplices', 'persistence_epsilon', 'invariant_epsilon'] 43 | if config.post_process != None : 44 | fields.extend(['post_process', 'post_process_arg']) 45 | 46 | return get_filename(config, fields, "Features", gz) 47 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/Kernel.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | #!/usr/bin/python 18 | from persistence.Datatypes.Configuration import Configuration 19 | from persistence.Datatypes.JSONObject import JSONObject, cond_get, cond_get_obj_list 20 | from persistence.Datatypes.Segments import SegmentInfo 21 | 22 | class Kernel(JSONObject) : 23 | fields = ['config', 24 | 'kernel_matrix', 25 | 'segment_info'] 26 | def __init__(self, config, kernel_matrix=None, segment_info=None): 27 | self.config = config 28 | self.kernel_matrix = kernel_matrix 29 | self.segment_info = segment_info 30 | 31 | @classmethod 32 | def fromJSONDict(cls, json): 33 | return cls(Configuration.fromJSONDict(json['config']), 34 | kernel_matrix=json['kernel_matrix'], 35 | segment_info=cond_get_obj_list(json, 'segment_info', SegmentInfo)) 36 | 37 | @staticmethod 38 | def get_kernel_filename(config, gz=True): 39 | raise NotImplementedError() 40 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/Learning.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | #!/usr/bin/python 18 | import os 19 | 20 | from persistence.Datatypes.JSONObject import JSONObject, cond_get, cond_get_obj_list 21 | from persistence.Datatypes.Configuration import Configuration, get_filename 22 | 23 | class LearningResult(JSONObject) : 24 | fields = ['seed', 25 | 'train_labels', 26 | 'test_labels', 27 | 'test_results', 28 | 'mkl_weights'] 29 | def __init__(self, seed, train_labels, test_labels, test_results, mkl_weights=None) : 30 | self.seed = seed 31 | self.train_labels = train_labels 32 | self.test_labels = test_labels 33 | self.test_results = test_results 34 | self.mkl_weights = mkl_weights 35 | 36 | @classmethod 37 | def fromJSONDict(cls, json) : 38 | return cls(cond_get(json, 'seed'), 39 | json['train_labels'], 40 | json['test_labels'], 41 | json['test_results'], 42 | cond_get(json, 'mkl_weights')) 43 | 44 | class Learning(JSONObject) : 45 | fields = ['config', 46 | 'results', 47 | 'kernel_files'] 48 | def __init__(self, config, results, kernel_files=None): 49 | self.config = config 50 | self.results = results 51 | self.kernel_files = None 52 | 53 | @classmethod 54 | def fromJSONDict(cls, json): 55 | return cls(Configuration.fromJSONDict(json['config']), 56 | cond_get_obj_list(json, 'results', LearningResult), 57 | cond_get(json, 'kernel_files')) 58 | 59 | def get_average_correct(self) : 60 | correct = [] 61 | for result in self.results : 62 | num_correct = reduce((lambda s, (t0, t1) : s + 1 if t0 == t1 else s), 63 | zip(result['test_labels'], result['test_results']), 0) 64 | correct.append(float(num_correct) / float(len(result['test_labels']))) 65 | import numpy 66 | return numpy.average(correct) 67 | 68 | @staticmethod 69 | def get_learning_filename(config, gz=True): 70 | fields = ['data_file', 'data_index', 'segment_size', 71 | 'segment_stride', 'window_size', 'window_stride', 72 | 'max_simplices', 'persistence_epsilon', 73 | 'kernel_scale', 'kernel_gamma', 'learning_C'] 74 | if config.post_process != None : 75 | fields.extend(['post_process', 'post_process_arg']) 76 | 77 | return get_filename(config, fields, "Learning", gz) 78 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/PersistenceDiagrams.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | #!/usr/bin/python 18 | import os 19 | from persistence.Datatypes.Configuration import Configuration, get_filename 20 | from persistence.Datatypes.JSONObject import JSONObject, cond_get, cond_get_obj_list 21 | from persistence.Datatypes.Segments import SegmentInfo 22 | 23 | class PersistenceDiagram(JSONObject): 24 | fields = ['segment_info', 25 | 'points'] 26 | 27 | def __init__(self, segment_info=None, points=None): 28 | self.segment_info = segment_info 29 | # Points are [birth, death, dimension] 30 | self.points = points 31 | 32 | @classmethod 33 | def fromJSONDict(cls, json): 34 | return cls(SegmentInfo.fromJSONDict(json['segment_info']) if 'segment_info' in json else None, 35 | points = cond_get(json, 'points')) 36 | 37 | class PersistenceDiagrams(JSONObject) : 38 | fields = ['config', 39 | 'diagrams'] 40 | def __init__(self, config, diagrams): 41 | self.config = config 42 | self.diagrams = diagrams 43 | 44 | @classmethod 45 | def fromJSONDict(cls, json): 46 | return cls(Configuration.fromJSONDict(json['config']), 47 | cond_get_obj_list(json, 'diagrams', PersistenceDiagram)) 48 | 49 | @staticmethod 50 | def get_iterable_field() : 51 | return 'diagrams' 52 | 53 | @staticmethod 54 | def get_persistence_diagrams_filename(config, gz=True): 55 | fields = ['data_file', 'data_index', 'segment_size', 56 | 'segment_stride', 'window_size', 'window_stride', 57 | 'max_simplices', 'persistence_epsilon'] 58 | if config.post_process != None : 59 | fields.extend(['post_process', 'post_process_arg']) 60 | 61 | return get_filename(config, fields, "PersistenceDiagrams", gz) 62 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/TrainTestPartitions.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | #!/usr/bin/python 18 | 19 | from persistence.Datatypes.JSONObject import JSONObject, cond_get, cond_get_obj_list 20 | from persistence.Datatypes.Configuration import Configuration, get_filename 21 | from persistence.Datatypes.Segments import SegmentInfo 22 | 23 | class TrainTestPartition(JSONObject) : 24 | fields = ['train', 25 | 'test', 26 | 'state'] 27 | def __init__(self, train=None, test=None, state=None) : 28 | self.train = train 29 | self.test = test 30 | self.state = state 31 | 32 | @classmethod 33 | def fromJSONDict(cls, json): 34 | return cls(train = cond_get(json, 'train'), 35 | test = cond_get(json, 'test'), 36 | state = cond_get(json, 'state')) 37 | 38 | 39 | class TrainTestPartitions(JSONObject) : 40 | fields = ['config', 41 | 'cross_validation', 42 | 'evaluation'] 43 | def __init__(self, config, segment_info=None, cross_validation=None, evaluation=None): 44 | self.config = config 45 | self.segment_info = segment_info 46 | self.cross_validation = cross_validation 47 | self.evaluation = evaluation 48 | 49 | @classmethod 50 | def fromJSONDict(cls, json): 51 | return cls(Configuration.fromJSONDict(json['config']), 52 | segment_info=cond_get_obj_list(json, 'segment_info', SegmentInfo), 53 | cross_validation=cond_get_obj_list(json, 'cross_validation', TrainTestPartition), 54 | evaluation=cond_get_obj_list(json, 'evaluation', TrainTestPartition)) 55 | 56 | @staticmethod 57 | def get_partition_filename(config, gz=True): 58 | fields = ['data_file', 'data_index', 'segment_size', 59 | 'segment_stride', 'window_size', 'window_stride'] 60 | 61 | return get_filename(config, fields, "Partition", gz) 62 | 63 | -------------------------------------------------------------------------------- /python/persistence/Datatypes/__init__.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | -------------------------------------------------------------------------------- /python/persistence/NormalizePost.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | import sys 19 | import argparse 20 | from scipy.fftpack import dct 21 | from numpy import array, ndarray 22 | 23 | from Datatypes.Configuration import get_filename 24 | from Datatypes.Segments import Segments, Segment 25 | from Datatypes.JSONObject import load_data, save_data 26 | 27 | def normalize(array) : 28 | scale = 1.0 / (sum(array) / len(array)) 29 | return [a * scale for a in array] 30 | 31 | class NormalizePost(Segments): 32 | @staticmethod 33 | def get_input_type(): 34 | return "Segments" 35 | 36 | @staticmethod 37 | def get_output_type(): 38 | return "Segments" 39 | 40 | def __init__(self, config, segments): 41 | super(self.__class__, self).__init__(config) 42 | transformed = [] 43 | for segment in segments : 44 | transform = [normalize(w) for w in segment.windows] 45 | transformed.append(Segment(windows=transform, 46 | segment_start=segment.segment_start, 47 | segment_size=segment.segment_size, 48 | window_stride=segment.window_stride, 49 | window_size=len(transform), 50 | labels=segment.labels, 51 | filename=segment.filename, 52 | data_index=segment.data_index, 53 | label_index=segment.label_index, 54 | learning=segment.learning)) 55 | self.segments = transformed 56 | 57 | @staticmethod 58 | def get_segment_filename(config, gz=True): 59 | fields = ['data_file', 'data_index', 'segment_size', 60 | 'segment_stride', 'window_size', 'window_stride'] 61 | return get_filename(config, fields, 'NormalizePost', gz) 62 | 63 | def main(argv): 64 | parser = argparse.ArgumentParser(description='Post Processing tool for Segment Data') 65 | parser.add_argument('-i', '--infile') 66 | parser.add_argument('-o', '--outfile') 67 | args = vars(parser.parse_args(argv[1:])) 68 | segments_json = load_data(args['infile'], 'segments', None, None, "NormalizePost: ") 69 | if segments_json == None : 70 | print "Could not load --infile : %s" % (args['infile'],) 71 | exit() 72 | segments = Segments.fromJSONDict(segments_json) 73 | segments.config.post_process="NormalizePost" 74 | post_processed = NormalizePost(segments.config, segments.segments) 75 | if args['outfile'] == None: 76 | outfile = NormalizePost.get_segment_filename(segments.config) 77 | else : 78 | outfile = args['outfile'] 79 | print "Writing %s" % outfile 80 | post_processed.config.status = "NormalizePost" 81 | save_data(outfile, post_processed.toJSONDict()) 82 | 83 | if __name__=="__main__" : 84 | main(sys.argv) 85 | -------------------------------------------------------------------------------- /python/persistence/WalkingSegments.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import time 18 | import sys 19 | import json 20 | import csv 21 | import itertools 22 | import argparse 23 | from Datatypes.Segments import Segments,Segment 24 | from Datatypes.Configuration import get_filename 25 | import os 26 | class WalkingSegments(Segments): 27 | """ 28 | Segments generated from the User Identification From Walking Activity 29 | https://archive.ics.uci.edu/ml/datasets/User+Identification+From+Walking+Activity 30 | 31 | Each data file corresponds to a separate individual, so the file name is used as our classification label. 32 | Each datapoint is read from the elements of each line, corresponding to the indices listed in config.data_index 33 | """ 34 | def __init__(self, config) : 35 | super(self.__class__, self).__init__(config) 36 | self.segments = [] 37 | if not isinstance(self.config.data_file, list) : 38 | self.config.data_file = [self.config.data_file] 39 | if self.config.window_size == -1 : 40 | self.config.window_size = self.config.segment_size 41 | for filename in self.config.data_file : 42 | with open(filename, 'r') as data_file : 43 | data_reader = csv.reader(data_file, delimiter=',') 44 | data = [[line[i] for i in self.config.data_index] for line in data_reader] 45 | for segment_start in range(0, len(data) - self.config.segment_size + 1, self.config.segment_stride) : 46 | segment_end = segment_start + self.config.segment_size 47 | self.segments.append( Segment(windows = [[float(item) for sublist in data[window_start:(window_start + self.config.window_size)] for item in sublist] 48 | for window_start in range(segment_start, segment_end - self.config.window_size + 1, self.config.window_stride)], 49 | segment_start=segment_start, 50 | segment_size=self.config.segment_size, 51 | window_stride=self.config.window_stride, 52 | window_size=self.config.window_size, 53 | labels=dict([(filename.split('/')[-1], segment_end - segment_start)]), 54 | filename=filename, 55 | data_index=self.config.data_index, 56 | label_index=self.config.label_index)) 57 | 58 | @staticmethod 59 | def get_segment_filename(config, gz=True): 60 | fields = ['data_file', 'data_index', 'segment_size', 'segment_stride', 'window_size', 'window_stride'] 61 | return get_filename(config, fields, 'WalkingSegments', gz) 62 | 63 | -------------------------------------------------------------------------------- /python/persistence/__init__.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | -------------------------------------------------------------------------------- /python/persistence/class_hierarchy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpersistence/tstop/495c6737f6c3540deb132bdd3798359bcbce4f96/python/persistence/class_hierarchy.pdf -------------------------------------------------------------------------------- /python/persistence/segment_persistence_plotter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpersistence/tstop/495c6737f6c3540deb132bdd3798359bcbce4f96/python/persistence/segment_persistence_plotter.png -------------------------------------------------------------------------------- /scripts/ChaosPost_stats.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import sys 18 | import numpy 19 | from persistence.Datatypes.JSONObject import load_data 20 | from persistence.Datatypes.Segments import Segments 21 | data = [] 22 | for arg in sys.argv[1:] : 23 | segments = Segments.fromJSONDict(load_data(arg, "segments", None, None, sys.argv[0] + ": ")) 24 | taus = [int(s.tau) for s in segments.segments] 25 | window_sizes = [len(s.windows[0]) for s in segments.segments] 26 | 27 | data.append([arg[arg.find('-data-')+6:arg.find('-seg-')], min(taus), max(taus), numpy.mean(taus),min(window_sizes), max(window_sizes), numpy.mean(window_sizes)]) 28 | 29 | data.sort() 30 | print data 31 | import matplotlib.pyplot as plt 32 | f = plt.figure() 33 | axes_tau = f.add_axes([0.1,0.3,0.35,0.6]) 34 | axes_tau.set_title("Time Delay") 35 | plots =[ 36 | axes_tau.bar(left=range(len(data)), height=[d[1] for d in data], bottom=0.0, width=0.8, color="#a8ddb5"), 37 | axes_tau.bar(left=range(len(data)), height=[d[2] - d[1] for d in data], bottom=[d[1] for d in data], width=0.8, color="#7bccc4"), 38 | axes_tau.bar(left=range(len(data)), height=[d[3] - d[2] for d in data], bottom=[d[2] for d in data], width=0.8, color="#4eb3d3") ] 39 | plt.legend(plots, ["Minimum", "Average", "Maximum"], ncol=3).draggable() 40 | axes_tau.set_xticks([x + 0.5 for x in range(len(data))]) 41 | axes_tau.set_xticklabels([d[0] for d in data], rotation=90) 42 | axes_win = f.add_axes([0.5,0.3,0.35,0.6]) 43 | axes_win.set_title("Window Size") 44 | axes_win.bar(left=range(len(data)), height=[d[4] for d in data], bottom=0.0, width=0.8, color="#a8ddb5") 45 | axes_win.bar(left=range(len(data)), height=[d[5] - d[4] for d in data], bottom=[d[4] for d in data], width=0.8, color="#7bccc4") 46 | axes_win.bar(left=range(len(data)), height=[d[6] - d[5] for d in data], bottom=[d[5] for d in data], width=0.8, color="#4eb3d3") 47 | axes_win.set_xticks([x + 0.5 for x in range(len(data))]) 48 | axes_win.set_xticklabels([d[0] for d in data], rotation=90) 49 | 50 | plt.show() 51 | -------------------------------------------------------------------------------- /scripts/activity_recognition.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import math 18 | import sys 19 | import csv 20 | import os 21 | import colorsys 22 | 23 | import matplotlib.pyplot as plt 24 | 25 | if(len(sys.argv) < 3): 26 | print 'insufficient args' 27 | sys.exit(1) 28 | 29 | window_size = 50 30 | window_stride = 1 31 | segment_size = 1500 32 | segment_stride = 30 33 | 34 | activity_file = open(sys.argv[1],'r') 35 | activity_reader = csv.reader(activity_file, delimiter=',') 36 | activity_data = [(float(x[1]),float(x[2]),float(x[3]),x[4]) for x in activity_reader] 37 | x_vals = range(len(activity_data)) 38 | unique_activities = set([x[3] for x in activity_data]) 39 | 40 | print 'list lengths:',len(x_vals),'',len(activity_data) 41 | 42 | activities = { '1' : 'Working at Computer' , '2' : 'Standing Up, Walking and Going up down stairs' , '3' : 'Standing' , '4' : 'Walking' , '5' : 'Going up down Stairs' , '6' : 'Walking and Talking with Someone' , '7' : 'Talking while Standing' } 43 | 44 | data_dir = sys.argv[2] 45 | 46 | for a in unique_activities: 47 | if a == '0': 48 | continue 49 | x_subset = [x for x,d in zip(x_vals,activity_data) if d[3] == a] 50 | d_subset = [d[0] for d in activity_data if d[3] == a] 51 | 52 | time_series_size = len(d_subset) 53 | for s in range(0,time_series_size-segment_size, segment_stride): 54 | segment_filename = data_dir + '/' + activities[a].replace(' ', '_') + '_segment' + '_' + str(s) + '.txt' 55 | segment_file = open(segment_filename, 'w') 56 | segment_file.write(str(a) + '\n') 57 | for t in range(s,(s+segment_size-window_size), window_stride): 58 | for i in range(t, t+window_size): 59 | sample = d_subset[i] 60 | if i < t+window_size-1: 61 | segment_file.write(str(sample) + ' ') 62 | else: 63 | segment_file.write(str(sample) + '\n') 64 | segment_file.close() 65 | 66 | all_plots = [] 67 | all_labels = [] 68 | plt.figure(figsize=(20,10)) 69 | for a in unique_activities: 70 | print 'plotting activity',a 71 | if a == '0': 72 | continue 73 | x_subset = [x for x,d in zip(x_vals,activity_data) if d[3] == a] 74 | d_subset = [d[0] for d in activity_data if d[3] == a] 75 | next_plot, = plt.plot(x_subset,d_subset) 76 | all_plots.append(next_plot) 77 | all_labels.append(activities[a]) 78 | #plt.plot( [d[2] for d in activity_data] ) 79 | #plt.plot( [d[3] for d in activity_data] ) 80 | leg = plt.legend( all_plots, all_labels, loc='upper right', shadow=True) 81 | 82 | for legobj in leg.legendHandles: 83 | legobj.set_linewidth(3.0) 84 | 85 | plt.show() 86 | -------------------------------------------------------------------------------- /scripts/bar_plot_from_csv.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | #!/usr/bin/env python 18 | import numpy as np 19 | import matplotlib.pyplot as plt 20 | import csv 21 | import sys 22 | import os 23 | import random 24 | 25 | with open(sys.argv[1],'r') as plot_file : 26 | plot_reader = csv.reader(plot_file, delimiter=',') 27 | full_data = [line for line in plot_reader] 28 | labels = full_data[0] 29 | data = full_data[1:] 30 | t_i = labels.index('Learning Type') 31 | c_i = labels.index('Correct') 32 | w_i = labels.index('Window Size') 33 | types = list(set(d[t_i] for d in data)) 34 | data = [(int(d[w_i]),d[t_i],float(d[c_i])) for d in data] 35 | 36 | data.sort() 37 | print data 38 | plots = [] 39 | width = 0.8 40 | windows = list(set([d[0] for d in data])) 41 | windows.sort() 42 | offset = [0.4 * x for x in range(len(windows))] 43 | for t in types : 44 | plots.append((t,plt.bar([x + offset[windows.index(data[x][0])] for x in range(len(data)) if data[x][1] == t], 45 | [d[2] * 100.0 for d in data if d[1] == t], width, 46 | color=(random.random(), random.random(), random.random())))) 47 | 48 | plt.ylabel('Percent Correct') 49 | plt.xlabel('Window Size') 50 | plt.title(sys.argv[1]) 51 | tick_labels = list(set([d[0] for d in data])) 52 | tick_labels.sort() 53 | tick_width = [len([d for d in data if d[0] == tick]) for tick in tick_labels] 54 | start = 0 55 | for x in range(len(tick_width)) : 56 | width = tick_width[x] 57 | tick_width[x] = start + tick_width[x] / 2.0 58 | start = start + width + 0.4 59 | plt.xticks(tick_width, tick_labels) 60 | plt.yticks(np.arange(0, 100, 10)) 61 | plt.legend([p[1][0] for p in plots], [p[0][0:-len("Learning")] for p in plots], loc="lower right") 62 | 63 | plt.show() 64 | -------------------------------------------------------------------------------- /scripts/migrate_data/distances.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import sys 18 | import argparse 19 | import importlib 20 | 21 | from persistence.Datatypes.JSONObject import load_data, save_data 22 | from persistence.Datatypes.Distances import Distances 23 | from persistence.Datatypes.Configuration import Configuration 24 | from persistence.Datatypes.Segments import SegmentInfo 25 | 26 | if __name__ == "__main__" : 27 | parser = argparse.ArgumentParser(description="Utility to add SegmentInfo data to a Distances file") 28 | parser.add_argument("--infile") 29 | parser.add_argument("--outfile") 30 | args = parser.parse_args(sys.argv[1:]) 31 | in_json = load_data(args.infile, "distances", None, None, sys.argv[0] + " : ") 32 | d = Distances.fromJSONDict(in_json) 33 | module = importlib.import_module('persistence.' + d.config.data_type) 34 | module_class = getattr(module, d.config.data_type) 35 | segment_filename = module_class.get_segment_filename(d.config) 36 | seg_json = load_data(segment_filename, "segments", None, None, sys.argv[0] + " : ") 37 | print segment_filename, len(seg_json['segments']) 38 | d.segment_info = [] 39 | i = 0 40 | for segment in seg_json['segments'] : 41 | d.segment_info.append(SegmentInfo.fromJSONDict(segment)) 42 | i = i + 1 43 | if i % 250 == 0: 44 | print segment_filename, i 45 | 46 | print "Writing %s" % (args.outfile,) 47 | save_data(args.outfile, d.toJSONDict()) 48 | -------------------------------------------------------------------------------- /scripts/migrate_data/kernel.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import sys 18 | import argparse 19 | import importlib 20 | 21 | from persistence.Datatypes.JSONObject import load_data, save_data 22 | from persistence.Datatypes.Kernel import Kernel 23 | from persistence.Datatypes.Configuration import Configuration 24 | from persistence.Datatypes.Segments import SegmentInfo 25 | 26 | if __name__ == "__main__" : 27 | parser = argparse.ArgumentParser(description="Utility to add SegmentInfo data to a Kernel file") 28 | parser.add_argument("--infile") 29 | parser.add_argument("--outfile") 30 | args = parser.parse_args(sys.argv[1:]) 31 | in_json = load_data(args.infile, "kernel", None, None, sys.argv[0] + " : ") 32 | k = Kernel.fromJSONDict(in_json) 33 | module = importlib.import_module('persistence.' + k.config.data_type) 34 | module_class = getattr(module, k.config.data_type) 35 | segment_filename = module_class.get_segment_filename(k.config) 36 | seg_json = load_data(segment_filename, "segments", None, None, sys.argv[0] + " : ") 37 | k.segment_info = [SegmentInfo.fromJSONDict(segment) for segment in seg_json['segments']] 38 | 39 | print "Writing %s" % (args.outfile,) 40 | save_data(args.outfile, k.toJSONDict()) 41 | -------------------------------------------------------------------------------- /scripts/migrate_data/persistences.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import sys 18 | import argparse 19 | import importlib 20 | 21 | from persistence.Datatypes.JSONObject import load_data, save_data 22 | from persistence.Datatypes.PersistenceDiagrams import PersistenceDiagrams, PersistenceDiagram 23 | from persistence.Datatypes.Configuration import Configuration 24 | from persistence.Datatypes.Segments import SegmentInfo 25 | 26 | if __name__ == "__main__" : 27 | parser = argparse.ArgumentParser(description="Utility to add SegmentInfo data to a PersistenceDiagrams file") 28 | parser.add_argument("--infile") 29 | parser.add_argument("--outfile") 30 | args = parser.parse_args(sys.argv[1:]) 31 | in_json = load_data(args.infile, "persistence diagrams", None, None, sys.argv[0] + " : ") 32 | pd = PersistenceDiagrams.fromJSONDict(in_json) 33 | module = importlib.import_module('persistence.' + pd.config.data_type) 34 | module_class = getattr(module, pd.config.data_type) 35 | segment_filename = module_class.get_segment_filename(pd.config) 36 | seg_json = load_data(segment_filename, "segments", None, None, sys.argv[0] + " : ") 37 | 38 | for (diagram, segment) in zip(pd.diagrams, seg_json['segments']) : 39 | diagram.segment_info = SegmentInfo.fromJSONDict(segment) 40 | 41 | print "Writing %s" % (args.outfile,) 42 | save_data(args.outfile, pd.toJSONDict()) 43 | -------------------------------------------------------------------------------- /scripts/pd_plotter.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import math 18 | import numpy as np 19 | import matplotlib.pyplot as plt 20 | from scipy import spatial 21 | import collections 22 | 23 | import sys 24 | import csv 25 | import os 26 | import random 27 | 28 | if(len(sys.argv) < 2): 29 | print 'insufficient args' 30 | sys.exit(1) 31 | 32 | pd_file = open(sys.argv[1],'r') 33 | pd_reader = csv.reader(pd_file, delimiter=' ') 34 | pd = np.array([[float(x[0]),float(x[1])] for x in pd_reader]) 35 | 36 | kd_tree = spatial.cKDTree(pd, 15) 37 | 38 | ave_r = 0 39 | the_k = 12 40 | for pt in pd: 41 | neighbor_dists,neighbor_idx = kd_tree.query(pt, the_k) 42 | ave_r += neighbor_dists[the_k-1] 43 | ave_r /= len(pd) 44 | 45 | scale_r = 1.1 46 | sigma = ave_r*scale_r 47 | query_r = 2.5*sigma 48 | 49 | all_neighbors = [kd_tree.query_ball_point(pt,query_r) for pt in pd] 50 | 51 | all_densities = []; 52 | for i in range(len(all_neighbors)): 53 | pt = pd[i] 54 | density = 0 55 | if pt[1]-pt[0] < 2e-1: 56 | all_densities.append(0) 57 | continue 58 | print 'pd:',pt 59 | for k in all_neighbors[i]: 60 | neighbor_pt = pd[k] 61 | diff_pt = neighbor_pt-pt 62 | sqd_dist = diff_pt[0]*diff_pt[0]+diff_pt[1]*diff_pt[1] 63 | density += math.exp(-sqd_dist/(sigma*sigma)) 64 | #density += -sqd_dist/(sigma*sigma) 65 | all_densities.append(density) 66 | 67 | fig = plt.figure() 68 | max_pd = max(pd[:,1]) 69 | min_pd = min(pd[:,0]) 70 | #print 'pd bounds:',min_pd,max_pd 71 | #print 'densities:',all_densities 72 | plt.scatter(pd[:,0],pd[:,1],color='blue', c=all_densities,s=10) 73 | plt.colorbar() 74 | #plt.plot([min_pd,max_pd],[min_pd,max_pd],color='black') 75 | plt.plot(x=[min_pd,max_pd],y=[min_pd,max_pd]) 76 | plt.show() 77 | -------------------------------------------------------------------------------- /scripts/pd_plotter_series.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import math 18 | import numpy as np 19 | import matplotlib.pyplot as plt 20 | import matplotlib.animation as animation 21 | from scipy import spatial 22 | import collections 23 | 24 | import sys 25 | import csv 26 | import os 27 | import random 28 | 29 | if(len(sys.argv) < 2): 30 | print 'insufficient args' 31 | sys.exit(1) 32 | base_file = sys.argv[1] 33 | 34 | def update_data(num, the_pds, scatter_plot): 35 | the_pd = the_pds[num] 36 | #scatter_plot.set_data(the_pds[:,0],the_pds[:,1]) 37 | scatter_plot.set_offsets(the_pds[:,0],the_pds[:,1]) 38 | 39 | def setup_plot: 40 | 41 | data_inds = range(400) 42 | fig = plt.figure() 43 | all_pds = [] 44 | first_pd = base_file+'10'+'.txt' 45 | for t in range(10,500): 46 | pd_filename = base_file+str(t)+'.txt' 47 | pd_file = open(pd_filename,'r') 48 | pd_reader = csv.reader(pd_file, delimiter=' ') 49 | pd = np.array([[float(x[0]),float(x[1])] for x in pd_reader]) 50 | all_pds.append(pd) 51 | 52 | #max_pd = max(pd[:,1]) 53 | #min_pd = min(pd[:,0]) 54 | #plt.scatter(pd[:,0],pd[:,1],color='blue', c=all_densities,s=10) 55 | first_pd = all_pds[0] 56 | fig,ax = plt.subplots() 57 | #l = plt.scatter(first_pd[:,0],first_pd[:,1]) 58 | #l, = plt.plot(x=[min_pd,max_pd],y=[min_pd,max_pd]) 59 | l_ani = animation.FuncAnimation(fig, update_data, 25, init_func=setup_plot, fargs=(data_inds, l)) 60 | -------------------------------------------------------------------------------- /scripts/persistence_density.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | import sys 19 | import math 20 | import itertools 21 | import multiprocessing 22 | 23 | from persistence.Datatypes.JSONObject import load_data, save_data 24 | from persistence.Datatypes.PersistenceDiagrams import PersistenceDiagrams, PersistenceDiagram 25 | def avg(l) : 26 | return sum(l,0.0) / len(l) 27 | def average_density(diagram) : 28 | points = [(p[0], p[1]) for p in diagram.points if p[2] == 1] 29 | if len(points) > 2 : 30 | diagram_distances = [] 31 | for (x0,y0) in points : 32 | distances = map(lambda (x1,y1) : math.sqrt((x0 - x1) * (x0 - x1) + (x0 - x1) * (x0 - x1)), points) 33 | diagram_distances.append(avg(distances[1:6])) 34 | return avg(diagram_distances) 35 | else : 36 | return 0.0 37 | 38 | 39 | 40 | if __name__ == "__main__" : 41 | pool = multiprocessing.Pool(multiprocessing.cpu_count() - 2) 42 | for f in sys.argv[1:] : 43 | pds = PersistenceDiagrams.fromJSONDict(load_data(f, None, None, None, sys.argv[0] + " : ")) 44 | densities = pool.map(average_density, pds.diagrams) 45 | save_data(f + "-density", list(densities)) 46 | -------------------------------------------------------------------------------- /scripts/plots/distance_mds.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | import sys 19 | import argparse 20 | import multiprocessing 21 | 22 | import numpy as np 23 | import matplotlib as mpl 24 | mpl.rcParams['font.size']=24 25 | mpl.rcParams['legend.fontsize']=20 26 | import matplotlib.pyplot as plt 27 | 28 | from sklearn import manifold 29 | 30 | from persistence.Datatypes.JSONObject import load_data 31 | from persistence.Datatypes.Distances import Distances, Distance 32 | from persistence.Datatypes.Learning import Learning, LearningResult 33 | 34 | parser = argparse.ArgumentParser() 35 | parser.add_argument("-l", "--learning", nargs="+") 36 | parser.add_argument("-d", "--distance-10") 37 | parser.add_argument("-e", "--distance-20") 38 | parser.add_argument("-f", "--distance-30") 39 | 40 | parser.add_argument("-p", "--pool", default=max(1,multiprocessing.cpu_count()-2), type=int) 41 | args = parser.parse_args(sys.argv[1:]) 42 | learning = [Learning.fromJSONDict(load_data(l,"learning", None, None, sys.argv[0] + ": ")) for l in args.learning] 43 | distances = [Distances.fromJSONDict(load_data(args.distance_10, "distances", None, None, sys.argv[0] + ": ")), 44 | Distances.fromJSONDict(load_data(args.distance_20, "distances", None, None, sys.argv[0] + ": ")), 45 | Distances.fromJSONDict(load_data(args.distance_30, "distances", None, None, sys.argv[0] + ": "))] 46 | filedict = [] 47 | f, axes = plt.subplots(2,2) 48 | colors_bright = ['red','green','orange','blue','violet'] 49 | colors = ['#d73027','#fc8d59','#fee090','#4575b4', '#91cf60', '#1a9850', '#91bfdb'] 50 | values = [] 51 | for l,f in zip(learning, args.learning) : 52 | correct = l.get_average_correct() 53 | if "PersistenceKernel" in f: 54 | tags = f.split('-') 55 | name = "Window Size %s" % (tags[tags.index('win')+1],) 56 | else : 57 | name = "RBFKernel" 58 | 59 | values.append((name,correct)) 60 | values.sort() 61 | i=0 62 | plots=[] 63 | for name, val in values : 64 | plots.append(axes[0][0].bar(i*10, val, color=colors[i], width=8)) 65 | i = i + 1 66 | axes[0][0].set_ylim(0.0,0.33,auto=False) 67 | axes[0][0].set_ylabel('Accuracy') 68 | axes[0][0].set_xticks([]) 69 | axes[0][0].legend(plots, [name for name,val in values], ncol=2).draggable() 70 | axes[0][0].set_title("Learning Results") 71 | 72 | ax_s = [axes[0][0],axes[0][1],axes[1][0],axes[1][1]] 73 | for d,ax in zip(distances, ax_s[1:]) : 74 | matrix = np.ndarray((len(d.segment_info),len(d.segment_info))) 75 | for i in range(len(d.segment_info)) : 76 | for j in range(i, len(d.segment_info)) : 77 | matrix[i][j] = d.distances[i][j].mean 78 | matrix[j][i] = matrix[i][j] 79 | 80 | mds = manifold.MDS(n_components=2, dissimilarity='precomputed', n_jobs=args.pool) 81 | 82 | points = mds.fit_transform(matrix) 83 | 84 | labels = [s.max_label() for s in d.segment_info] 85 | 86 | labeled = dict([(label, [p for (p,l) in zip(points, labels) if l == label]) for label in list(set(labels))]) 87 | 88 | labels = list(set(labels)) 89 | labels.sort() 90 | label_ind = dict([(str(l), i) for (l,i) in zip(labels, range(len(labels)))]) 91 | for k,v in labeled.iteritems() : 92 | xs = [p[0] for p in v] 93 | ys = [p[1] for p in v] 94 | ax.scatter(xs,ys,c=colors_bright[(label_ind[str(k)]*4) % len(colors_bright)], linewidth=0, s=50) 95 | ax.set_title("Window Size %s" % (d.config.window_size)) 96 | 97 | plt.show() 98 | -------------------------------------------------------------------------------- /scripts/plots/ucr_csv_results.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import os 18 | import sys 19 | import argparse 20 | import csv 21 | import numpy as np 22 | import matplotlib.pyplot as plt 23 | 24 | infile = sys.argv[1] 25 | full_data = [] 26 | keys = None 27 | with open(infile, 'rb') as csvfile : 28 | values = csv.reader(csvfile, delimiter=',') 29 | 30 | for row in values : 31 | if keys == None: 32 | keys = [v for v in row if v != ''] 33 | else : 34 | data = dict(zip(keys, row)) 35 | full_data.append(data) 36 | 37 | plot_data = [(data['Dataset'], 38 | data['Data Type'], 39 | float(data['RBF'][0:-1])/100.0 if data['RBF'] != '' else None, 40 | float(data['Window Size 10'][0:-1])/100.0 if data['Window Size 10'] != '' else None, 41 | float(data['Window Size 20'][0:-1])/100.0 if data['Window Size 20'] != '' else None, 42 | float(data['Window Size 30'][0:-1])/100.0 if data['Window Size 30'] != '' else None, 43 | ) for data in full_data] 44 | 45 | 46 | fig = plt.figure() 47 | ax = fig.add_axes([0.1, 0.3, 0.8, 0.65]) 48 | plot_data = [p for p in plot_data if p[2] != None and p[3] != None and p[4] != None and p[5] != None] 49 | plot_data.sort(key=(lambda x: "%s %0.2f" % (x[1], max(x[2:])))) 50 | rbf_xs = [x*9 for x in range(len(plot_data))] 51 | pk_xs = [x*9+3 for x in range(len(plot_data))] 52 | rbf = [p[2] for p in plot_data] 53 | win = [[], [], []] 54 | for p in plot_data: 55 | order = zip(p[3:], [0,1,2]) 56 | order.sort() 57 | win[order[0][1]].append((0.0, order[0][0])) 58 | win[order[1][1]].append((order[0][0], order[1][0] - order[0][0])) 59 | win[order[2][1]].append((order[1][0], order[2][0] - order[1][0])) 60 | 61 | plots = [] 62 | plots.append(ax.bar(left=rbf_xs, height=rbf, width=3, color="#DB7D2B")) 63 | plots.append(ax.bar(left=pk_xs, height=[w[1] for w in win[0]], width=3, bottom=[w[0] for w in win[0]], color="#a8ddb5")) 64 | plots.append(ax.bar(left=pk_xs, height=[w[1] for w in win[1]], width=3, bottom=[w[0] for w in win[1]], color="#7bccc4")) 65 | plots.append(ax.bar(left=pk_xs, height=[w[1] for w in win[2]], width=3, bottom=[w[0] for w in win[2]], color="#4eb3d3")) 66 | ax.set_ylabel("Accuracy") 67 | ax.set_xticks(pk_xs) 68 | ax.set_xticklabels([p[0] for p in plot_data], rotation=90) 69 | plt.legend(plots, ("RBF Kernel", "Window Size 10", "Window Size 20", "Window Size 30"), ncol=4).draggable() 70 | 71 | plt.show() 72 | -------------------------------------------------------------------------------- /scripts/scatter_anim_example.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import matplotlib.pyplot as plt 18 | 19 | import sys 20 | import csv 21 | import os 22 | import random 23 | 24 | plt.ion() 25 | class DynamicUpdate(): 26 | #Suppose we know the x range 27 | min_x = 4 28 | max_x = 6.5 29 | 30 | def on_launch(self): 31 | #Set up plot 32 | self.figure, self.ax = plt.subplots(2) 33 | self.pd_plotter, = self.ax[0].plot([],[], 'o') 34 | self.ts_plotter, = self.ax[1].plot([2], 'r-') 35 | #Autoscale on unknown axis and known lims on the other 36 | #self.ax.set_autoscaley_on(True) 37 | self.ax[0].set_xlim(self.min_x, self.max_x) 38 | self.ax[0].set_ylim(self.min_x, self.max_x) 39 | self.ax[1].set_autoscaley_on(True) 40 | self.ax[1].set_autoscalex_on(True) 41 | #Other stuff 42 | #self.ax.grid() 43 | #... 44 | 45 | def on_running(self, xdata, ydata, ts_data_x, ts_data_y): 46 | #Update data (with the new _and_ the old points) 47 | self.pd_plotter.set_xdata(xdata) 48 | self.pd_plotter.set_ydata(ydata) 49 | self.ts_plotter.set_xdata(ts_data_x[len(ts_data_x)-1]) 50 | self.ts_plotter.set_ydata(ts_data_y[len(ts_data_y)-1]) 51 | #Need both of these in order to rescale 52 | self.ax[1].relim() 53 | self.ax[1].autoscale_view() 54 | #We need to draw *and* flush 55 | self.figure.canvas.draw() 56 | self.figure.canvas.flush_events() 57 | 58 | #Example 59 | def __call__(self): 60 | import numpy as np 61 | import time 62 | self.on_launch() 63 | base_file = '../build/pd-' 64 | first_pd = base_file+'10'+'.txt' 65 | ts_filename = '../build/time_series.txt' 66 | time_series_file = open(ts_filename,'r') 67 | time_series_reader = csv.reader(time_series_file, delimiter=' ') 68 | all_ts_vals = np.array([[x[0],x[1]] for x in time_series_reader]) 69 | for t in range(10,40000): 70 | pd_filename = base_file+str(t)+'.txt' 71 | pd_file = open(pd_filename,'r') 72 | pd_reader = csv.reader(pd_file, delimiter=' ') 73 | pd = np.array([[float(x[0]),float(x[1])] for x in pd_reader if not (float(x[0]) == float(x[1]))]) 74 | ts_vals_x = all_ts_vals[10:t+1,0] 75 | ts_vals_y = all_ts_vals[10:t+1,1] 76 | self.on_running(pd[:,0], pd[:,1], ts_vals_x,ts_vals_y) 77 | #time.sleep(0.01) 78 | return xdata, ydata 79 | 80 | d = DynamicUpdate() 81 | d() 82 | -------------------------------------------------------------------------------- /scripts/simple_time_series_plotter.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import math 18 | import sys 19 | import csv 20 | import os 21 | import colorsys 22 | 23 | import matplotlib.pyplot as plt 24 | import numpy as np 25 | 26 | if(len(sys.argv) < 2): 27 | print 'insufficient args' 28 | sys.exit(1) 29 | 30 | time_series_file = open(sys.argv[1],'r') 31 | time_series_reader = csv.reader(time_series_file, delimiter=' ') 32 | all_vals = np.array([[x[0],x[1]] for x in time_series_reader]) 33 | plt.figure(figsize=(20,10)) 34 | plt.plot(all_vals[:,1]) 35 | plt.show() 36 | -------------------------------------------------------------------------------- /scripts/window_data.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | """ 18 | Script to take a segmented data set where segment_size == 19 | window_size and extract a single dimension from the data and write it 20 | to a windowed data file 21 | """ 22 | 23 | import os 24 | import sys 25 | import argparse 26 | import importlib 27 | from persistence.Datatypes.JSONObject import load_data, save_data 28 | from persistence.Datatypes.Segments import Segments, Segment 29 | 30 | 31 | parser = argparse.ArgumentParser(description="Creates windowed segments of a single dimension for a multidimensioned dataset") 32 | parser.add_argument("-i","--infile") 33 | parser.add_argument("-d","--data-index", default=0, type=int) 34 | parser.add_argument("-w","--window-size", type=int) 35 | parser.add_argument("-W","--window-stride", default=1, type=int) 36 | args = parser.parse_args(sys.argv[1:]) 37 | segments = Segments.fromJSONDict(load_data(args.infile, "segments", None, None, sys.argv[0] + ": ")) 38 | orig_window_size = segments.config.window_size 39 | segments.config.window_size = args.window_size 40 | segments.config.window_stride = args.window_stride 41 | dimensions = len(segments.segments[0].data_index) 42 | segments.config.data_index = segments.segments[0].data_index[args.data_index] 43 | for segment in segments.segments : 44 | windows = [[segment.windows[0][(i + j) * dimensions + args.data_index] for j in range(args.window_size)] 45 | for i in range(0, orig_window_size, args.window_stride) if ((i + args.window_size - 1) * dimensions + args.data_index) < len(segment.windows[0])] 46 | segment.data_index = segment.data_index[args.data_index] 47 | segment.window_size = args.window_stride 48 | segment.windows = windows 49 | segment_module = importlib.import_module("persistence." + segments.config.data_type) 50 | segment_class = getattr(segment_module, segments.config.data_type) 51 | segment_filename = segment_class.get_segment_filename(segments.config) 52 | print "Writing " + segment_filename 53 | save_data(segment_filename, segments.toJSONDict()) 54 | -------------------------------------------------------------------------------- /scripts/wrong.py: -------------------------------------------------------------------------------- 1 | #TSTOP 2 | # 3 | #This program is free software: you can redistribute it and/or modify 4 | #it under the terms of the GNU General Public License as published by 5 | #the Free Software Foundation, either version 3 of the License, or 6 | #(at your option) any later version. 7 | # 8 | #This program is distributed in the hope that it will be useful, 9 | #but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | #GNU General Public License for more details. 12 | # 13 | #You should have received a copy of the GNU General Public License 14 | #along with this program. If not, see . 15 | 16 | 17 | import sys 18 | from persistence.Datatypes.JSONObject import load_data 19 | from persistence.Datatypes.Learning import Learning, LearningResult 20 | from persistence.Datatypes.TrainTestPartitions import TrainTestPartitions 21 | 22 | partitions_json = load_data(sys.argv[1], 'partition', None, None, sys.argv[0] + ": ") 23 | partitions = TrainTestPartitions.fromJSONDict(partitions_json) 24 | all_wrongs = [] 25 | for f in sys.argv[2:] : 26 | results_json = load_data(f, 'learning', None, None, sys.argv[0] + ": ") 27 | results = Learning.fromJSONDict(results_json) 28 | wrongs = [] 29 | for (result, partition) in zip(results.results, partitions.evaluation) : 30 | correct = [(l == r) for (l,r) in zip(result.test_labels, result.test_results)] 31 | wrong = [p for (c,p) in zip(correct, partition.test) if not c] 32 | wrong.sort() 33 | wrongs.append(wrong) 34 | all_wrongs.append(wrongs) 35 | 36 | for (a,b) in zip(all_wrongs[0], all_wrongs[1]) : 37 | if a == b : 38 | print "identical" 39 | else : 40 | print "not identical" 41 | -------------------------------------------------------------------------------- /topology/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${tstop_SOURCE_DIR}/topology ${tstop_SOURCE_DIR}/ext/geom_dist/wasserstein/include ${tstop_SOURCE_DIR}/ext/geom_dist/bottleneck/include ${Boost_INCLUDE_DIR}) 2 | file(GLOB topology_sources ${tstop_SOURCE_DIR}/topology/*.cpp ${tstop_SOURCE_DIR}/topology/*.h) 3 | 4 | find_package(PythonInterp 2.7) 5 | find_package(PythonLibs 2.7) 6 | find_package(NumPy 1.7.1) 7 | find_package(Boost 1.46 COMPONENTS python) 8 | 9 | set(CMAKE_CXX_FLAGS "-std=c++11") 10 | if(OPENMP_FOUND) 11 | message("Got OpenMP!") 12 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 14 | endif() 15 | include_directories(${PYTHON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) 16 | add_library(topology SHARED ${topology_sources}) 17 | target_link_libraries(topology geometry wasserstein bottleneck ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) 18 | add_dependencies(topology ann geometry) 19 | 20 | add_library(py_persistence SHARED python/py_persistence.cpp) 21 | target_link_libraries(py_persistence topology geometry wasserstein bottleneck ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) 22 | add_dependencies(py_persistence topology geometry) 23 | set_target_properties(py_persistence PROPERTIES PREFIX "" OUTPUT_NAME "py_persistence") 24 | 25 | set(__linkname "${tstop_SOURCE_DIR}/python/persistence/py_persistence.so") 26 | Add_custom_command(TARGET py_persistence POST_BUILD COMMAND ln -sf $ "${__linkname}") 27 | #set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES "${__linkname}") 28 | -------------------------------------------------------------------------------- /topology/ComputationTimer.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "ComputationTimer.h" 19 | 20 | ComputationTimer::ComputationTimer(string _computation) : computation(_computation) {} 21 | ComputationTimer::~ComputationTimer() {} 22 | -------------------------------------------------------------------------------- /topology/ComputationTimer.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef COMPUTATIONTIMER_H 19 | #define COMPUTATIONTIMER_H 20 | 21 | #include 22 | #include 23 | using namespace std; 24 | 25 | class ComputationTimer { 26 | public: 27 | ComputationTimer(string _computation); 28 | ~ComputationTimer(); 29 | 30 | void start() { computation_start = clock(); } 31 | void end() { 32 | computation_end = clock(); 33 | total_time = ((double)(computation_end-computation_start)) / CLOCKS_PER_SEC; 34 | } 35 | 36 | string getComputation() { return computation; } 37 | double getElapsedTime() { return total_time; } 38 | void dump_time() { cout << computation << " : " << total_time << " s " << endl; } 39 | 40 | private: 41 | clock_t computation_start, computation_end; 42 | double total_time; 43 | string computation; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /topology/bottleneck_distance.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include "bottleneck_distance.h" 22 | #include "persistence_diagram.h" 23 | 24 | using namespace boost::python; 25 | 26 | #include "bottleneck.h" 27 | double BottleneckDistance::bottleneck_distance(object persist_1, 28 | object persist_2, 29 | object degree) 30 | { 31 | boost::python::list p1_list = extract(persist_1); 32 | boost::python::list p2_list = extract(persist_2); 33 | std::vector> p1; 34 | std::vector> p2; 35 | int p1_len = len(p1_list); 36 | int p2_len = len(p2_list); 37 | int deg = extract(degree); 38 | for (int i=0; i < p1_len; ++i) { 39 | boost::python::list val = extract(p1_list[i]); 40 | if (extract(val[2]) == deg) { 41 | p1.push_back(std::pair( extract(val[0]), extract(val[1]))); 42 | } 43 | } 44 | for (int i=0; i < p2_len; ++i) { 45 | boost::python::list val = extract(p2_list[i]); 46 | if (extract(val[2]) == deg) { 47 | p2.push_back(std::pair( extract(val[0]), extract(val[1]))); 48 | } 49 | } 50 | 51 | if (p1.size() != 0 and p2.size() != 0) { 52 | return geom_bt::bottleneckDistApproxInterval(p1, p2, 0.01 /* relative error, 1% */).first; 53 | } else { 54 | return -1.0; 55 | } 56 | } 57 | #include "wasserstein.h" 58 | double BottleneckDistance::wasserstein_distance(object persist_1, 59 | object persist_2, 60 | object degree, 61 | object power) 62 | { 63 | boost::python::list p1_list = extract(persist_1); 64 | boost::python::list p2_list = extract(persist_2); 65 | std::vector> p1; 66 | std::vector> p2; 67 | int p1_len = len(p1_list); 68 | int p2_len = len(p2_list); 69 | int deg = extract(degree); 70 | int pow = extract(power); 71 | for (int i=0; i < p1_len; ++i) { 72 | boost::python::list val = extract(p1_list[i]); 73 | if (extract(val[2]) == deg) { 74 | p1.push_back(std::pair( extract(val[0]), extract(val[1]))); 75 | } 76 | } 77 | for (int i=0; i < p2_len; ++i) { 78 | boost::python::list val = extract(p2_list[i]); 79 | if (extract(val[2]) == deg) { 80 | p2.push_back(std::pair( extract(val[0]), extract(val[1]))); 81 | } 82 | } 83 | if (p1.size() != 0 and p2.size() != 0) { 84 | return geom_ws::wassersteinDist(p1,p2, pow, 0.01 /* relative error, 1% */, 85 | std::numeric_limits::infinity() /* internal norm */); 86 | } else { 87 | return -1.0; 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /topology/bottleneck_distance.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef BOTTLENECK_DISTANCE_H 19 | #define BOTTLENECK_DISTANCE_H 1 20 | #include 21 | #include "persistence_diagram.h" 22 | namespace BottleneckDistance { 23 | boost::python::list match_points(boost::python::object persistence_1, 24 | boost::python::object persistence_2, 25 | boost::python::object degree); 26 | double bottleneck_distance(boost::python::object persistence_1, 27 | boost::python::object persistence_2, 28 | boost::python::object degree); 29 | double wasserstein_distance(boost::python::object persistence_1, 30 | boost::python::object persistence_2, 31 | boost::python::object degree, 32 | boost::python::object power); 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /topology/distance_learning/knn_persistence_classifier.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "knn_persistence_classifier.h" 19 | 20 | KNNPersistenceClassifier::KNNPersistenceClassifier(const std::vector & _trainingPDs, const std::vector & _trainingInds) { 21 | training_pds = _trainingPDs; 22 | training_inds = _trainingInds; 23 | 24 | // extract possible labels 25 | for(int i = 0; i < training_pds.size(); i++) 26 | all_labels.insert(training_pds[i].label); 27 | } 28 | 29 | KNNPersistenceClassifier::~KNNPersistenceClassifier() { 30 | } 31 | 32 | int KNNPersistenceClassifier::knn_prediction(const PersistenceDiagram & _testPD, int _d, int _k) { 33 | std::vector sorted_persistence; 34 | for(int i = 0; i < _testPD.num_pairs(); i++) { 35 | PersistentPair pair = _testPD.get_pair(i); 36 | if(pair.dim() != _d) 37 | continue; 38 | double persistence = _testPD.get_pair(i).l_inf_diagonal(); 39 | sorted_persistence.push_back(IndexedDouble(i,persistence)); 40 | } 41 | std::sort(sorted_persistence.begin(),sorted_persistence.end()); 42 | /* 43 | for(int i = 0; i < sorted_persistence.size(); i++) { 44 | std::cout << "distance to diagonal["< sorted_neighbors(training_pds.size(),IndexedDouble(0,0)); 50 | int i = 0; 51 | //#pragma omp parallel for 52 | for(i = 0; i < training_pds.size(); i++) { 53 | //std::cout << "wasserstein distance for PD " << i << " ; " << training_pds[i].pd.num_pairs() << " : " << _testPD.num_pairs() << " ..." << std::endl; 54 | double wasserstein_distance = training_pds[i].pd.wasserstein_distance(_testPD,_d,1); 55 | //std::cout << "wasserstein distance["< label_votes; 62 | for(std::set::iterator label_iter = all_labels.begin(); label_iter != all_labels.end(); ++label_iter) 63 | label_votes[*label_iter] = 0; 64 | for(int k = 0; k < _k; k++) { 65 | int neighbor_label = training_pds[sorted_neighbors[k].ind].label; 66 | label_votes[neighbor_label]=label_votes[neighbor_label]+1; 67 | std::cout << "neighbor label["< " << sorted_neighbors[k].value << " ; " << training_inds[sorted_neighbors[k].ind] << std::endl; 68 | /* 69 | int pd_ind = sorted_neighbors[k].ind; 70 | std::cout << "persistence pairings:" << std::endl; 71 | for(int i = 0; i < training_pds[pd_ind].pd.num_pairs(); i++) { 72 | PersistentPair pairing = training_pds[pd_ind].pd.get_pair(i); 73 | if(pairing.d != 1) 74 | continue; 75 | std::cout << "( " << pairing.birth << " , " << pairing.death << " )" << std::endl; 76 | } 77 | */ 78 | } 79 | int highest_count = 0, predicted_label = 0; 80 | for(std::set::iterator label_iter = all_labels.begin(); label_iter != all_labels.end(); ++label_iter) { 81 | int next_label = *label_iter; 82 | if(label_votes[next_label] > highest_count) { 83 | highest_count = label_votes[next_label]; 84 | predicted_label = next_label; 85 | } 86 | } 87 | 88 | return predicted_label; 89 | } 90 | -------------------------------------------------------------------------------- /topology/distance_learning/knn_persistence_classifier.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef KNN_PERSISTENCE_CLASSIFIER_H 19 | #define KNN_PERSISTENCE_CLASSIFIER_H 20 | 21 | #include "../persistence_diagram.h" 22 | #include 23 | 24 | class KNNPersistenceClassifier { 25 | public: 26 | KNNPersistenceClassifier(const std::vector & _trainingPDs, const std::vector & _trainingInds); 27 | ~KNNPersistenceClassifier(); 28 | 29 | int knn_prediction(const PersistenceDiagram & _testPD, int _d, int _k=1); 30 | 31 | private: 32 | std::vector training_pds; 33 | std::vector training_inds; 34 | 35 | std::set all_labels; 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /topology/dtw_python.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | /** 19 | * dtw_python.cpp 20 | * 21 | * Interface between the python time series functionality and the 22 | * dynamic time warping nearest neighbor functions in dtw.h from 23 | * Daniel Lemire at https://github.com/lemire/lbimproved 24 | * 25 | * Nov 1 2015 Shelby Davis davis@brsc.com 26 | * Govt POC: Lee Seversky AFRL / RISA Lee.Seversky@us.af.mil 27 | */ 28 | 29 | #include 30 | #include 31 | #include "dtw.h" 32 | #include "dtw_python.hpp" 33 | 34 | using namespace boost::python; 35 | 36 | boost::python::list DTW_python::nearest_neighbor(boost::python::object time_series_train, 37 | boost::python::object time_series_test) 38 | { 39 | boost::python::list ts_train_list = extract(time_series_train); 40 | boost::python::list ts_test_list = extract(time_series_test); 41 | std::vector> train_sets; 42 | int train_len = len(ts_train_list); 43 | for (int i = 0; i < train_len; ++i) { 44 | boost::python::list train_element_py = extract(ts_train_list[i]); 45 | std::vector train_element; 46 | int train_element_len = len(train_element_py); 47 | for (int j=0; j < train_element_len; ++j) { 48 | train_element.push_back(extract(train_element_py[j])); 49 | } 50 | train_sets.push_back(train_element); 51 | } 52 | 53 | boost::python::list result; 54 | int test_len = len(ts_test_list); 55 | for (int i=0; i < test_len; ++i) { 56 | boost::python::list test_element_py = extract(ts_test_list[i]); 57 | std::vector test_element; 58 | int test_element_len = len(test_element_py); 59 | for (int j=0; j < test_element_len; ++j) { 60 | test_element.push_back(extract(test_element_py[j])); 61 | } 62 | LB_Improved nn(test_element, test_element_len / 10.0); // Arbitrarily set the window at 10% 63 | int match = -1; 64 | double best_distance = nn.getLowestCost(); 65 | for (int j=0; j < train_len; ++j) { 66 | double new_distance = nn.test(train_sets[j]); 67 | if (new_distance < best_distance) { 68 | best_distance = new_distance; 69 | match = j; 70 | } 71 | } 72 | result.append(boost::python::make_tuple(match, best_distance)); 73 | } 74 | return result; 75 | } 76 | 77 | double DTW_python::distance(boost::python::object segment_a, 78 | boost::python::object segment_b) 79 | { 80 | boost::python::list segment_a_py = extract(segment_a); 81 | std::vector segment_a_element; 82 | int segment_a_len = len(segment_a_py); 83 | for (int j=0; j < segment_a_len; ++j) { 84 | segment_a_element.push_back(extract(segment_a_py[j])); 85 | } 86 | 87 | boost::python::list segment_b_py = extract(segment_b); 88 | std::vector segment_b_element; 89 | int segment_b_len = len(segment_b_py); 90 | for (int j=0; j < segment_b_len; ++j) { 91 | segment_b_element.push_back(extract(segment_b_py[j])); 92 | } 93 | 94 | LB_Improved nn(segment_a_element, segment_a_len / 10.0); // Arbitrarily set the window at 10% 95 | 96 | double distance = nn.test(segment_b_element); 97 | return distance; 98 | } 99 | -------------------------------------------------------------------------------- /topology/dtw_python.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DTW_PYTHON_H 2 | #define DTW_PYTHON_H 1 3 | 4 | #include 5 | 6 | namespace DTW_python { 7 | /* nearest_neigbor returns a list of tuples (index, distance) of the 8 | * nearest neighbot in the training set for each element in the test 9 | * set. */ 10 | boost::python::list nearest_neighbor(boost::python::object time_series_train, 11 | boost::python::object time_series_test); 12 | /* distance returns the DTW distance between two segments*/ 13 | double distance(boost::python::object segment_a, 14 | boost::python::object segment_b); 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /topology/euclidean_space.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "euclidean_space.h" 19 | 20 | EuclideanSpace::EuclideanSpace(const Points & _points) : MetricSpace(_points.size()) { 21 | points = _points; 22 | } 23 | 24 | EuclideanSpace::~EuclideanSpace() { 25 | } 26 | 27 | double EuclideanSpace::distance(int _i, int _j) { 28 | return points[_i].length(points[_j]); 29 | } 30 | -------------------------------------------------------------------------------- /topology/euclidean_space.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef EUCLIDEANSPACE_H 19 | #define EUCLIDEANSPACE_H 20 | 21 | #include "metric_space.h" 22 | #include "../geometry/point_incs.h" 23 | 24 | class EuclideanSpace : public MetricSpace { 25 | public: 26 | EuclideanSpace(const Points & _points); 27 | ~EuclideanSpace(); 28 | 29 | virtual double distance(int _i, int _j); 30 | 31 | private: 32 | Points points; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /topology/filtration.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "filtration.h" 19 | 20 | Filtration::Filtration(int _maxD) { 21 | max_d = _maxD; 22 | } 23 | 24 | Filtration::~Filtration() { 25 | } 26 | 27 | bool Filtration::build_filtration() { 28 | return false; 29 | } 30 | -------------------------------------------------------------------------------- /topology/filtration.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef FILTRATION_H 19 | #define FILTRATION_H 20 | 21 | #include "../geometry/point_incs.h" 22 | #include "simplex.h" 23 | #include 24 | 25 | class Filtration { 26 | public: 27 | Filtration(int _maxD); 28 | ~Filtration(); 29 | 30 | Simplex get_simplex(int _t) { return all_simplices[_t]; } 31 | int filtration_size() { return all_simplices.size(); } 32 | 33 | int maxD() { return max_d; } 34 | 35 | virtual bool build_filtration(); 36 | 37 | protected: 38 | std::vector all_simplices; 39 | 40 | private: 41 | int max_d; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /topology/fps_rips_filtration.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef FPSRIPSFILTRATION_H 19 | #define FPSRIPSFILTRATION_H 20 | 21 | #include "rips_filtration.h" 22 | 23 | class FPSRipsFiltration : public RipsFiltration { 24 | 25 | public: 26 | FPSRipsFiltration(const Points & _points, int _maxD, double _eps=1.5); 27 | FPSRipsFiltration(int _numPoints, double** _distanceMat, int _maxD, double _eps=1.5); 28 | ~FPSRipsFiltration(); 29 | 30 | virtual bool build_filtration(); 31 | 32 | private: 33 | double eps; 34 | std::vector deletion_times; 35 | 36 | void sparse_bron_kerbosch(std::vector* _rips, std::vector _R, const std::set & _P, int _maxD); 37 | 38 | void fps(int* sampling, double* fps_distances); 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /topology/generalized_metric_space.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "generalized_metric_space.h" 19 | 20 | GeneralizedMetricSpace::GeneralizedMetricSpace(int _numPoints, double** _distances) : MetricSpace(_numPoints) { 21 | distances = _distances; 22 | } 23 | 24 | GeneralizedMetricSpace::~GeneralizedMetricSpace() { 25 | } 26 | 27 | double GeneralizedMetricSpace::distance(int _i, int _j) { 28 | return distances[_i][_j]; 29 | } 30 | -------------------------------------------------------------------------------- /topology/generalized_metric_space.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef GENERALIZEDMETRICSPACE_H 19 | #define GENERALIZEDMETRICSPACE_H 20 | 21 | #include "metric_space.h" 22 | #include 23 | 24 | class GeneralizedMetricSpace : public MetricSpace { 25 | public: 26 | GeneralizedMetricSpace(int _numPoints, double** _distances); 27 | ~GeneralizedMetricSpace(); 28 | 29 | virtual double distance(int _i, int _j); 30 | 31 | private: 32 | double** distances; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /topology/landscape_distance.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include 19 | #include 20 | #include "hungarianC.h" 21 | #include "persistenceBarcode.h" 22 | #include "persistenceLandscape.h" 23 | #include "landscape_distance.h" 24 | #include 25 | 26 | using namespace boost::python; 27 | 28 | double Landscape::distance(object persist_1, object persist_2, object degree) { 29 | boost::python::list p1_list = extract(persist_1); 30 | boost::python::list p2_list = extract(persist_2); 31 | std::vector> p1; 32 | std::vector> p2; 33 | int p1_len = len(p1_list); 34 | int p2_len = len(p2_list); 35 | int deg = extract(degree); 36 | for (int i=0; i < p1_len; ++i) { 37 | boost::python::list val = extract(p1_list[i]); 38 | if (extract(val[2]) == deg) { 39 | double start = extract(val[0]); 40 | double end = extract(val[1]); 41 | p1.push_back(std::make_pair(start, end)); 42 | } 43 | } 44 | for (int i=0; i < p2_len; ++i) { 45 | boost::python::list val = extract(p2_list[i]); 46 | if (extract(val[2]) == deg) { 47 | double start = extract(val[0]); 48 | double end = extract(val[1]); 49 | p2.push_back(std::make_pair(start,end)); 50 | } 51 | } 52 | PersistenceBarcodes b1(p1); 53 | PersistenceBarcodes b2(p2); 54 | PersistenceLandscape l1(b1); 55 | PersistenceLandscape l2(b2); 56 | return computeDiscanceOfLandscapes(l1,l2,2); 57 | } 58 | -------------------------------------------------------------------------------- /topology/landscape_distance.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef LANDSCAPE_DISTANCE_H 19 | #define LANDSCAPE_DISTANCE_H 1 20 | #include 21 | namespace Landscape { 22 | double distance(boost::python::object persistence_1, 23 | boost::python::object persistence_2, 24 | boost::python::object degree); 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /topology/metric_space.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "metric_space.h" 19 | 20 | MetricSpace::MetricSpace(int _numPoints) : num_points(_numPoints) {} 21 | MetricSpace::~MetricSpace() {} 22 | -------------------------------------------------------------------------------- /topology/metric_space.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef METRICSPACE_H 19 | #define METRICSPACE_H 20 | 21 | class MetricSpace { 22 | public: 23 | MetricSpace(int _numPoints); 24 | ~MetricSpace(); 25 | 26 | virtual double distance(int _i, int _j) = 0; 27 | 28 | private: 29 | int num_points; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /topology/persistence.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef PERSISTENCE_H 19 | #define PERSISTENCE_H 20 | 21 | #include "persistence_diagram.h" 22 | 23 | #include "filtration.h" 24 | #include "sparse_rips_filtration.h" 25 | #include "rips_filtration.h" 26 | #include 27 | #include 28 | #include "ComputationTimer.h" 29 | 30 | typedef std::list PHCycle; 31 | 32 | class PersistentHomology { 33 | public: 34 | PersistentHomology(bool _retainGenerators=false); 35 | PersistentHomology(Filtration* _filtration, bool _retainGenerators=false); 36 | ~PersistentHomology(); 37 | 38 | PersistenceDiagram *compute_persistence_sparse(SparseRipsFiltration *, int _maxD); 39 | PersistenceDiagram *compute_persistence_full(RipsFiltration *, int _maxD); 40 | 41 | PHCycle merge_cycles(const PHCycle & _c1, const PHCycle & _c2); 42 | 43 | private: 44 | Filtration* filtration; 45 | int max_d; 46 | bool retain_generators; 47 | 48 | std::list expand_chain(int _chain, PHCycle* _allChains); 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /topology/persistence_dataset.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "persistence_dataset.h" 19 | 20 | PersistenceDataset::PersistenceDataset(std::string _filename, double _trainingPerc) { 21 | training_perc = _trainingPerc; 22 | std::ifstream pds_file(_filename.c_str()); 23 | if(pds_file.fail()) { 24 | std::cerr << "bad persistence diagrams filename! " << _filename << std::endl; 25 | return; 26 | } 27 | 28 | std::map label_mapping; 29 | int line_length = 50*1024*1024; 30 | char* line_raw = new char[line_length]; 31 | for(;;) { 32 | pds_file.getline(line_raw, line_length); 33 | if(pds_file.eof()) 34 | break; 35 | 36 | std::string line(line_raw); 37 | std::vector tokens; 38 | this->tokenize_line(&tokens, line, ","); 39 | 40 | std::string label_name = tokens[0]; 41 | if(label_mapping.find(label_name) == label_mapping.end()) 42 | label_mapping[label_name] = label_mapping.size(); 43 | int label_id = label_mapping[label_name]; 44 | std::vector all_pairs; 45 | for(int i = 1; i < tokens.size(); i+=3) { 46 | int dim = atoi(tokens[i].c_str()); 47 | double birth = atof(tokens[i+1].c_str()), death = atof(tokens[i+2].c_str()); 48 | all_pairs.push_back(PersistentPair(dim,birth,death)); 49 | } 50 | labeled_persistence_diagrams.push_back(LabeledPersistenceDiagram(PersistenceDiagram(all_pairs),label_id)); 51 | all_labels.insert(label_id); 52 | } 53 | 54 | pds_file.close(); 55 | } 56 | 57 | PersistenceDataset::~PersistenceDataset() {} 58 | 59 | void PersistenceDataset::training_shuffle() { 60 | if(training_inds.size() > 0) { 61 | training_inds.clear(); 62 | test_inds.clear(); 63 | } 64 | 65 | int num_training = labeled_persistence_diagrams.size()*training_perc; 66 | std::vector permuted_inds; 67 | for(int i = 0; i < labeled_persistence_diagrams.size(); i++) 68 | permuted_inds.push_back(i); 69 | for(int i = 0; i < num_training; i++) { 70 | int rand_ind = rand() % (labeled_persistence_diagrams.size()-i); 71 | int permuted_index = permuted_inds[rand_ind]; 72 | training_inds.push_back(permuted_index); 73 | permuted_inds[rand_ind] = permuted_inds[labeled_persistence_diagrams.size()-i-1]; 74 | } 75 | for(int i = num_training; i < labeled_persistence_diagrams.size(); i++) { 76 | int rand_ind = rand() % (labeled_persistence_diagrams.size()-i); 77 | int permuted_index = permuted_inds[rand_ind]; 78 | test_inds.push_back(permuted_index); 79 | permuted_inds[rand_ind] = permuted_inds[labeled_persistence_diagrams.size()-i-1]; 80 | } 81 | } 82 | 83 | void PersistenceDataset::tokenize_line(std::vector* tokens, const std::string& input, std::string sep) { 84 | std::string comm; 85 | for (int i = 0; i < input.size(); i++) { 86 | const char ch = input[i]; 87 | bool added = false; 88 | for (int s = 0; s < sep.size(); s++) { 89 | if (ch == sep[s]) { 90 | if(comm.size() > 0) 91 | tokens->push_back(comm); 92 | comm = ""; 93 | added = true; 94 | break; 95 | } 96 | } 97 | if (!added) 98 | comm += ch; 99 | } 100 | if (comm != "") 101 | tokens->push_back(comm); 102 | } 103 | -------------------------------------------------------------------------------- /topology/persistence_dataset.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef PERSISTENCE_DATASET_H 19 | #define PERSISTENCE_DATASET_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "persistence_diagram.h" 29 | 30 | class PersistenceDataset { 31 | public: 32 | PersistenceDataset(std::string _filename, double _trainingPerc=0.5); 33 | ~PersistenceDataset(); 34 | 35 | int size() { return labeled_persistence_diagrams.size(); } 36 | LabeledPersistenceDiagram get_pd(int _i) { return labeled_persistence_diagrams[_i]; } 37 | 38 | void training_shuffle(); 39 | 40 | int training_size() { 41 | return training_inds.size(); 42 | } 43 | 44 | std::vector get_training_inds() { return training_inds; } 45 | std::vector get_test_inds() { return test_inds; } 46 | 47 | LabeledPersistenceDiagram get_training_pd(int _i) const { 48 | return labeled_persistence_diagrams[(training_inds[_i])]; 49 | } 50 | 51 | int test_size() { 52 | return test_inds.size(); 53 | } 54 | 55 | LabeledPersistenceDiagram get_test_pd(int _i) const { 56 | return labeled_persistence_diagrams[(test_inds[_i])]; 57 | } 58 | 59 | private: 60 | double training_perc; 61 | std::vector labeled_persistence_diagrams; 62 | std::set all_labels; 63 | std::vector training_inds; 64 | std::vector test_inds; 65 | 66 | void tokenize_line(std::vector* tokens, const std::string& input, std::string sep); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /topology/relaxed_metric_space.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "relaxed_metric_space.h" 19 | 20 | RelaxedMetricSpace::RelaxedMetricSpace(const SparsePoints & _points, const std::vector & _deletionTimes, double _eps) : MetricSpace(_points.size()) { 21 | points = _points; 22 | deletion_times = _deletionTimes; 23 | eps = _eps; 24 | time_scale = 1; 25 | 26 | cached_distances = new double*[points.size()]; 27 | for(int i = 0; i < points.size(); i++) { 28 | cached_distances[i] = new double[points.size()]; 29 | for(int j = 0; j < points.size(); j++) 30 | cached_distances[i][j] = -1; 31 | } 32 | } 33 | 34 | RelaxedMetricSpace::~RelaxedMetricSpace() { 35 | for(int i = 0; i < points.size(); i++) 36 | delete [] cached_distances[i]; 37 | delete [] cached_distances; 38 | } 39 | 40 | double RelaxedMetricSpace::distance(int _i, int _j) { 41 | double numer_eps = 1e-15; 42 | std::pair pairing = _i < _j ? std::pair(_i,_j) : std::pair(_j,_i); 43 | double local_dist = 0; 44 | /* 45 | if(distance_map.find(pairing) == distance_map.end()) { 46 | local_dist = points[_i].length(points[_j]); 47 | distance_map[pairing] = local_dist; 48 | } 49 | else 50 | local_dist = distance_map[pairing]; 51 | */ 52 | int smaller_ind = _i < _j ? _i : _j; 53 | int larger_ind = _i > _j ? _i : _j; 54 | if(cached_distances[smaller_ind][larger_ind] == -1) { 55 | local_dist = points[_i].length(points[_j]); 56 | cached_distances[smaller_ind][larger_ind] = local_dist; 57 | } 58 | else 59 | local_dist = cached_distances[smaller_ind][larger_ind]; 60 | 61 | double t_p = time_scale*deletion_times[_i], t_q = time_scale*deletion_times[_j]; 62 | if(t_q < t_p) { 63 | double temp_t = t_p; 64 | t_p = t_q; 65 | t_q = temp_t; 66 | } 67 | if(local_dist <= (1-2*eps)*t_p) 68 | return local_dist; 69 | 70 | double alpha_1 = 2*local_dist - (1-2*eps)*t_p; 71 | if(alpha_1 > (1-2*eps)*t_p && alpha_1 < t_p && alpha_1 <= (1-2*eps)*t_q) 72 | return alpha_1; 73 | 74 | double alpha_2 = local_dist/(1-eps); 75 | if(alpha_2 >= (t_p-numer_eps) && alpha_2 <= ((1-2*eps)*t_q+numer_eps)) 76 | return alpha_2; 77 | 78 | double alpha_3 = local_dist/(1-2*eps); 79 | if(alpha_3 >= t_p && alpha_3 >= t_q) 80 | return alpha_3; 81 | 82 | double alpha_4 = (local_dist-0.5*(1-2*eps)*t_q) / (0.5-eps); 83 | if(alpha_4 >= t_p && alpha_4 > (1-2*eps)*t_q && alpha_4 < t_q) 84 | return alpha_4; 85 | 86 | std::cout << "unknown alpha case! " << local_dist << " t_p: " << t_p << " ; t_q: " << t_q << std::endl; 87 | double min_alpha_p = (1-2*eps)*t_p, max_alpha_p = t_p; 88 | double min_alpha_q = (1-2*eps)*t_q, max_alpha_q = t_q; 89 | std::cout << "min alpha_p: " << min_alpha_p << " ; max alpha_p: " << max_alpha_p << " ; min alpha_q: " << min_alpha_q << " ; max alpha_q: " << max_alpha_q << std::endl; 90 | std::cout << "alpha_1: " << alpha_1 << " ; alpha_2: " << alpha_2 << " ; alpha_3: " << alpha_3 << " ; alpha_4: " << alpha_4 << std::endl; 91 | 92 | return alpha_1; 93 | } 94 | -------------------------------------------------------------------------------- /topology/relaxed_metric_space.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef RELAXEDMETRICSPACE_H 19 | #define RELAXEDMETRICSPACE_H 20 | 21 | #include "metric_space.h" 22 | #include 23 | #include 24 | #include "../geometry/point_incs.h" 25 | 26 | class RelaxedMetricSpace : public MetricSpace { 27 | public: 28 | RelaxedMetricSpace(const SparsePoints & _points, const std::vector & _deletionTimes, double _eps); 29 | ~RelaxedMetricSpace(); 30 | 31 | double get_time_scale() { return time_scale; } 32 | void set_time_scale(double _scale) { time_scale = _scale; } 33 | 34 | double get_deletion_time(int _i) { return time_scale*deletion_times[_i]; } 35 | 36 | virtual double distance(int _i, int _j); 37 | 38 | private: 39 | SparsePoints points; 40 | std::vector deletion_times; 41 | std::map, double> distance_map; 42 | double** cached_distances; 43 | double eps; 44 | double time_scale; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /topology/rips_filtration.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef RIPSFILTRATION_H 19 | #define RIPSFILTRATION_H 20 | 21 | #include "filtration.h" 22 | #include "generalized_metric_space.h" 23 | 24 | class RipsFiltration : public Filtration { 25 | public: 26 | RipsFiltration(const Points & _points, int _maxD); 27 | RipsFiltration(int _numPoints, double** _distanceMat, int _maxD); 28 | RipsFiltration(int _numPoints, int _maxD); 29 | ~RipsFiltration(); 30 | 31 | void global_bron_kerbosch(std::vector* _rips, std::vector _R, const std::set & _P, int _maxD); 32 | 33 | virtual bool build_filtration(); 34 | 35 | 36 | void set_distance(int _i, int _j, double _v); 37 | void build_metric(); 38 | 39 | protected: 40 | int num_points; 41 | double** distances; 42 | MetricSpace* metric_space; 43 | 44 | private: 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /topology/rips_python.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | /** 19 | * rips_python.cpp 20 | * 21 | * Interface between the python time series functionality and 22 | * the sparse and full rips filtration in C++ 23 | * 24 | * Dec 4 2015 Shelby Davis davis@brsc.com 25 | * Govt POC: Lee Seversky AFRL / RISA Lee.Seversky@us.af.mil 26 | */ 27 | 28 | #include 29 | #include 30 | #include "filtration.h" 31 | #include "generalized_metric_space.h" 32 | #include "rips_python.hpp" 33 | 34 | using namespace boost::python; 35 | 36 | 37 | /* points is a list of lists of floats, corresponding to the 'windows' field in a Segment in python */ 38 | RipsFiltration* RIPS_python::rips_filtration_generator(boost::python::object points, 39 | boost::python::object max_d) 40 | { 41 | int _max_d = extract(max_d); 42 | boost::python::list points_list = extract(points); 43 | int points_len = len(points_list); 44 | Points c_points; 45 | for (int i = 0; i < points_len; ++i) { 46 | c_points.push_back(Vector(points_list[i])); 47 | } 48 | 49 | RipsFiltration *result = new RipsFiltration(c_points, _max_d); 50 | 51 | return result; 52 | } 53 | 54 | SparseRipsFiltration* RIPS_python::sparse_rips_filtration_generator(boost::python::object points, 55 | boost::python::object max_simplices, 56 | boost::python::object epsilon, 57 | boost::python::object max_d) 58 | { 59 | int _max_d = extract(max_d); 60 | boost::python::list points_list = extract(points); 61 | int points_len = len(points_list); 62 | Points c_points; 63 | for (int i = 0; i < points_len; ++i) { 64 | c_points.push_back(Vector(points_list[i])); 65 | } 66 | 67 | SparseRipsFiltration *result = NULL; 68 | if (!max_simplices.is_none()) { 69 | result = new SparseRipsFiltration(c_points, _max_d); 70 | result->set_max_simplices(extract(max_simplices)); 71 | } else if (!epsilon.is_none()) { 72 | result = new SparseRipsFiltration(c_points, _max_d, extract(epsilon)); 73 | } else { 74 | result = new SparseRipsFiltration(c_points, _max_d); 75 | } 76 | 77 | return result; 78 | } 79 | -------------------------------------------------------------------------------- /topology/rips_python.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RIPS_PYTHON_H 2 | #define RIPS_PYTHON_H 1 3 | 4 | #include "topology/rips_filtration.h" 5 | #include "topology/sparse_rips_filtration.h" 6 | #include 7 | 8 | namespace RIPS_python { 9 | SparseRipsFiltration *sparse_rips_filtration_generator(boost::python::object points, 10 | boost::python::object max_simplices, 11 | boost::python::object epsilon, 12 | boost::python::object max_d); 13 | RipsFiltration *rips_filtration_generator(boost::python::object points, 14 | boost::python::object max_d); 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /topology/scale_space_kernel.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include "scale_space_kernel.h" 22 | 23 | double ScaleSpaceKernel::similarity(boost::python::object list_1, 24 | boost::python::object list_2, 25 | double sigma) 26 | { 27 | int list_len_1 = boost::python::len(list_1); 28 | int list_len_2 = boost::python::len(list_2); 29 | if (list_len_1 <= 1 || list_len_2 <= 1) 30 | { 31 | return 0.0; 32 | } 33 | boost::python::list _list_1 = boost::python::extract(list_1); 34 | boost::python::list _list_2 = boost::python::extract(list_2); 35 | 36 | std::unique_ptr l1(new double[list_len_1*2]); 37 | for (int i=0; i < list_len_1; i++) 38 | { 39 | boost::python::tuple _l1 = boost::python::extract(_list_1[i]); 40 | l1[i*2 + 0] = boost::python::extract(_l1[0]); 41 | l1[i*2 + 1] = boost::python::extract(_l1[1]); 42 | } 43 | std::unique_ptr l2(new double[list_len_2*2]); 44 | for (int j=0; j < list_len_2; j++) 45 | { 46 | boost::python::tuple _l2 = boost::python::extract(_list_2[j]); 47 | l2[j*2 + 0] = boost::python::extract(_l2[0]); 48 | l2[j*2 + 1] = boost::python::extract(_l2[1]); 49 | } 50 | double scale = -1.0 / sigma / 8.0; 51 | double accum = 0.0; 52 | for (int i=0; i < list_len_1; i++) 53 | { 54 | double l1_x = l1[i*2+0]; 55 | double l1_y = l1[i*2+1]; 56 | for (int j=0; j < list_len_2; j++) 57 | { 58 | double l2_x = l2[j*2+0]; 59 | double l2_y = l2[j*2+1]; 60 | double xx = l1_x - l2_x; 61 | double yy = l1_y - l2_y; 62 | double xy = l1_x - l2_y; 63 | double yx = l1_y - l2_x; 64 | accum += 65 | std::exp((xx * xx + yy * yy) * scale) - 66 | std::exp((xy * xy + yx * yx) * scale); 67 | } 68 | } 69 | return accum / (8.0 * sigma * M_PI); 70 | } 71 | -------------------------------------------------------------------------------- /topology/scale_space_kernel.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef SCALE_SPACE_KERNEL_H 19 | #define SCALE_SPACE_KERNEL_H 1 20 | namespace ScaleSpaceKernel { 21 | double similarity(boost::python::object list_1, boost::python::object list_2, double sigma); 22 | }; 23 | 24 | #endif /* SCALE_SPACE_KERNEL_H */ 25 | -------------------------------------------------------------------------------- /topology/segment_dataset.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "segment_dataset.h" 19 | 20 | SegmentDataset::SegmentDataset(std::string _filename, double _trainingPerc) { 21 | training_perc = _trainingPerc; 22 | std::ifstream segments_file(_filename.c_str()); 23 | if(segments_file.fail()) { 24 | std::cerr << "bad segments filename! " << _filename << std::endl; 25 | return; 26 | } 27 | 28 | std::map label_mapping; 29 | int line_length = 50*1024*1024; 30 | char* line_raw = new char[line_length]; 31 | for(;;) { 32 | segments_file.getline(line_raw, line_length); 33 | if(segments_file.eof()) 34 | break; 35 | 36 | std::string line(line_raw); 37 | std::vector tokens; 38 | this->tokenize_line(&tokens, line, ","); 39 | 40 | std::string label_name = tokens[0]; 41 | if(label_mapping.find(label_name) == label_mapping.end()) 42 | label_mapping[label_name] = label_mapping.size(); 43 | int label_id = label_mapping[label_name]; 44 | Eigen::VectorXd segment = Eigen::VectorXd::Zero(tokens.size()-1); 45 | for(int i = 1; i < tokens.size(); i++) 46 | segment(i-1) = atof(tokens[i].c_str()); 47 | labeled_segments.push_back(LabeledSegment(segment,label_id)); 48 | all_labels.insert(label_id); 49 | } 50 | 51 | segments_file.close(); 52 | } 53 | 54 | SegmentDataset::~SegmentDataset() {} 55 | 56 | void SegmentDataset::training_shuffle() { 57 | if(training_inds.size() > 0) { 58 | training_inds.clear(); 59 | test_inds.clear(); 60 | } 61 | 62 | int num_training = labeled_segments.size()*training_perc; 63 | std::vector permuted_inds; 64 | for(int i = 0; i < labeled_segments.size(); i++) 65 | permuted_inds.push_back(i); 66 | for(int i = 0; i < num_training; i++) { 67 | int rand_ind = rand() % (labeled_segments.size()-i); 68 | int permuted_index = permuted_inds[rand_ind]; 69 | training_inds.push_back(permuted_index); 70 | permuted_inds[rand_ind] = permuted_inds[labeled_segments.size()-i-1]; 71 | } 72 | for(int i = num_training; i < labeled_segments.size(); i++) { 73 | int rand_ind = rand() % (labeled_segments.size()-i); 74 | int permuted_index = permuted_inds[rand_ind]; 75 | test_inds.push_back(permuted_index); 76 | permuted_inds[rand_ind] = permuted_inds[labeled_segments.size()-i-1]; 77 | } 78 | } 79 | 80 | void SegmentDataset::tokenize_line(std::vector* tokens, const std::string& input, std::string sep) { 81 | std::string comm; 82 | for (int i = 0; i < input.size(); i++) { 83 | const char ch = input[i]; 84 | bool added = false; 85 | for (int s = 0; s < sep.size(); s++) { 86 | if (ch == sep[s]) { 87 | if(comm.size() > 0) 88 | tokens->push_back(comm); 89 | comm = ""; 90 | added = true; 91 | break; 92 | } 93 | } 94 | if (!added) 95 | comm += ch; 96 | } 97 | if (comm != "") 98 | tokens->push_back(comm); 99 | } 100 | -------------------------------------------------------------------------------- /topology/segment_dataset.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef SEGMENT_DATASET_H 19 | #define SEGMENT_DATASET_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | struct LabeledSegment { 33 | LabeledSegment(const Eigen::VectorXd & _segment, int _label) : segment(_segment) , label(_label) {} 34 | Eigen::VectorXd segment; 35 | int label; 36 | }; 37 | 38 | class SegmentDataset { 39 | public: 40 | SegmentDataset(std::string _filename, double _trainingPerc=0.5); 41 | ~SegmentDataset(); 42 | 43 | int size() { return labeled_segments.size(); } 44 | LabeledSegment get_segment(int _i) { return labeled_segments[_i]; } 45 | 46 | void training_shuffle(); 47 | 48 | int training_size() { 49 | return training_inds.size(); 50 | } 51 | 52 | std::vector get_training_inds() { return training_inds; } 53 | std::vector get_test_inds() { return test_inds; } 54 | 55 | LabeledSegment get_training_segment(int _i) const { 56 | return labeled_segments[(training_inds[_i])]; 57 | } 58 | 59 | int test_size() { 60 | return test_inds.size(); 61 | } 62 | 63 | LabeledSegment get_test_segment(int _i) const { 64 | return labeled_segments[(test_inds[_i])]; 65 | } 66 | 67 | private: 68 | double training_perc; 69 | std::vector labeled_segments; 70 | std::set all_labels; 71 | std::vector training_inds; 72 | std::vector test_inds; 73 | 74 | void tokenize_line(std::vector* tokens, const std::string& input, std::string sep); 75 | }; 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /topology/simplex.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #include "simplex.h" 19 | 20 | Simplex::Simplex(const std::vector & _simplex, MetricSpace* _metricSpace) { 21 | simplex = _simplex; 22 | metric_space = _metricSpace; 23 | cached_distance = 0; 24 | } 25 | 26 | Simplex::~Simplex() { 27 | } 28 | 29 | std::vector Simplex::faces() { 30 | std::vector all_faces; 31 | for(unsigned i = 0; i < simplex.size(); i++) { 32 | std::vector new_face; 33 | for(unsigned j = 0; j < simplex.size()-1; j++) { 34 | int next_vertex = simplex[(j+i)%simplex.size()]; 35 | new_face.push_back(next_vertex); 36 | } 37 | all_faces.push_back(Simplex(new_face,metric_space)); 38 | } 39 | return all_faces; 40 | } 41 | -------------------------------------------------------------------------------- /topology/simplex.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef SIMPLEX_H 19 | #define SIMPLEX_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "metric_space.h" 28 | 29 | class Simplex { 30 | public: 31 | Simplex() {} 32 | Simplex(const std::vector & _simplex, MetricSpace* _metricSpace); 33 | ~Simplex(); 34 | 35 | int dim() const { return simplex.size()-1; } 36 | int vertex(int _i) const { return simplex[_i]; } 37 | double get_simplex_distance() const { 38 | return cached_distance; 39 | } 40 | 41 | void compute_simplex_distance() { 42 | for(unsigned i = 0; i < simplex.size(); i++) { 43 | for(unsigned j = 0; j < i; j++) { 44 | double next_dist = metric_space->distance(simplex[i],simplex[j]); 45 | cached_distance = next_dist > cached_distance ? next_dist : cached_distance; 46 | } 47 | } 48 | } 49 | 50 | std::string unique_unoriented_id() const { 51 | std::vector sorted_simplex = simplex; 52 | std::sort(sorted_simplex.begin(),sorted_simplex.end()); 53 | char unique_id[10*(sorted_simplex.size()+1)]; 54 | sprintf(unique_id, "%u", sorted_simplex[0]); 55 | for(unsigned i = 1; i < sorted_simplex.size(); i++) 56 | sprintf(unique_id, "%s-%u", unique_id, sorted_simplex[i]); 57 | return unique_id; 58 | } 59 | 60 | std::vector faces(); 61 | 62 | inline bool operator<(const Simplex& _simp) const { 63 | int our_dim = this->dim(), other_dim = _simp.dim(); 64 | // lower dimensional simplices come before higher dimensional ones 65 | /* 66 | if(our_dim < other_dim) 67 | return true; 68 | else if(other_dim < our_dim) 69 | return false; 70 | */ 71 | 72 | // if dimensions are 0, then just use index for comparison 73 | if(our_dim==0 && other_dim==0) 74 | return simplex[0] < _simp.vertex(0); 75 | 76 | // otherwise, take largest edge distance on simplex for comparison 77 | double our_edge_dist = this->get_simplex_distance(), other_edge_dist = _simp.get_simplex_distance(); 78 | if(our_edge_dist < other_edge_dist) 79 | return true; 80 | if(other_edge_dist < our_edge_dist) 81 | return false; 82 | 83 | // if they are equivalent, then lower dimensional simplices precede higher dimensional ones 84 | return our_dim < other_dim; 85 | 86 | // TODO: resolve equal distance, equal dim? 87 | } 88 | 89 | friend std::ostream& operator <<(std::ostream &out, const Simplex & _simplex) { 90 | for(int i = 0; i <= _simplex.dim(); i++) { 91 | out << " " << _simplex.vertex(i); 92 | } 93 | return out; 94 | } 95 | 96 | private: 97 | std::vector simplex; 98 | MetricSpace* metric_space; 99 | double cached_distance; 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /topology/sparse_persistence.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef SPARSEPERSISTENCE_H 19 | #define SPARSEPERSISTENCE_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "../geometry/point_incs.h" 34 | #include "persistence_diagram.h" 35 | 36 | using namespace std; 37 | 38 | #define CHRIS_VERBOSE 0 39 | 40 | typedef struct sinf { 41 | string str;//TODO: Make this a pointer? 42 | size_t index; 43 | size_t k;//Number of vertices in the simplex 44 | double dist; 45 | } SimplexInfo; 46 | 47 | typedef struct bdt { 48 | double birth; 49 | double death; 50 | } BDTimes; 51 | 52 | struct Simplex_DistComparator { 53 | bool operator()(SimplexInfo* s1, SimplexInfo* s2) const { 54 | if (s1->dist < s2->dist) { 55 | return true; 56 | } 57 | else if (s1->dist == s2->dist) { 58 | //Make sure to add the faces of a simplex before adding the simplex 59 | return s1->k < s2->k; 60 | } 61 | return false; 62 | } 63 | }; 64 | 65 | class SparsePersistence { 66 | public: 67 | SparsePersistence(const Points & _points, const std::vector & _levels, double _ctScale, int _maxD); 68 | ~SparsePersistence(); 69 | 70 | void printMatrix(vector* M, int n, int m); 71 | double getSqrDist(int i, int j); 72 | void getEdgeRelaxedDist(int p, int q, double* ts, int* e1, int* e2, double* ed); 73 | void getEdgeUnwarpedDist(int p, int q, double* ts, int* e1, int* e2, double* ed); 74 | void getCoDim1CliqueStrings(vector& cocliques, string str); 75 | void addCliquesFromProximityList(vector& Ep, map& EDists, map* simplices, int MaxBetti); 76 | void addColToColMod2(vector& col1, vector& col2); 77 | void addLowElementToOthers(vector* M, int col, list& nzc); 78 | PersistenceDiagram compute_persistence(); 79 | 80 | private: 81 | int max_d; 82 | Points points; 83 | std::vector levels; 84 | double ct_scale; 85 | }; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /topology/sparse_rips_filtration.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef SPARSERIPSFILTRATION_H 19 | #define SPARSERIPSFILTRATION_H 20 | 21 | #include "filtration.h" 22 | #include "ComputationTimer.h" 23 | #include "../geometry/covertree.h" 24 | #include 25 | #include "relaxed_metric_space.h" 26 | 27 | class SparseRipsFiltration : public Filtration { 28 | 29 | public: 30 | SparseRipsFiltration(const Points & _points, std::vector _levels, std::vector _parents, int _maxD, double _eps=1/3.0); 31 | SparseRipsFiltration(const Points & _points, int _maxD, double _eps=1/3.0); 32 | SparseRipsFiltration(int _maxD, double _eps=1/3.0); 33 | ~SparseRipsFiltration(); 34 | 35 | void build_cover_tree(); 36 | virtual bool build_filtration(); 37 | 38 | void set_max_simplices(int _maxSimplices) { max_simplices = _maxSimplices; } 39 | 40 | void add_point(const Vector & _pt); 41 | 42 | void set_random_seed(int _seed); 43 | 44 | double get_simplex_sparsity(int _i) { return simplex_sparsity[_i]; } 45 | 46 | private: 47 | double eps; 48 | SparsePoints points; 49 | std::vector deletion_times; 50 | CoverTree* cover_tree; 51 | 52 | bool is_initialized; 53 | 54 | int max_simplices; 55 | int num_points; 56 | RelaxedMetricSpace* metric_space; 57 | std::vector simplex_sparsity; 58 | 59 | void bf_bron_kerbosch(std::vector* _rips, std::vector _R, const std::set & _P, int _maxD); 60 | void sparse_bron_kerbosch(std::vector* _rips, std::set _P, int _maxD); 61 | 62 | void build_point_weights(); 63 | void build_modified_distances(); 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /topology/zero_persistence_python.cpp: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | /** 19 | * zero_persistence_python.cpp 20 | * 21 | * Interface between python code and the code for calculating zero dimensional persistence diagrams 22 | * 23 | * April 22 2016 Shelby davis davis@brsc.com 24 | * Govt POC: Lee Seversky AFRL / RISA Lee.Seversky@us.af.mil 25 | */ 26 | 27 | #include "zero_persistence_python.h" 28 | 29 | using namespace boost::python; 30 | 31 | void ZeroDimensionPersistence::add_function_value(boost::python::object index, 32 | boost::python::object time, 33 | boost::python::object value) { 34 | // std::cout << "Adding point " << extract(index) << " time " << extract(time) << " value " << extract(value) << std::endl; 35 | this->function_values.push_back(FunctionValue(extract(index), extract(time), extract(value))); 36 | } 37 | 38 | boost::python::list ZeroDimensionPersistence::sweep_persistence() { 39 | ZeroPersistence p = ZeroPersistence(this->function_values); 40 | p.sweep_persistence(); 41 | std::vector > zero_pd; 42 | p.get_root()->compute_all_pairs(zero_pd); 43 | boost::python::list pairs; 44 | for (std::vector >::iterator it = zero_pd.begin(); it != zero_pd.end(); ++it) { 45 | pairs.append(boost::python::make_tuple((*it).first, (*it).second)); 46 | } 47 | return pairs; 48 | } 49 | -------------------------------------------------------------------------------- /topology/zero_persistence_python.h: -------------------------------------------------------------------------------- 1 | //TSTOP 2 | // 3 | //This program is free software: you can redistribute it and/or modify 4 | //it under the terms of the GNU General Public License as published by 5 | //the Free Software Foundation, either version 3 of the License, or 6 | //(at your option) any later version. 7 | // 8 | //This program is distributed in the hope that it will be useful, 9 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | //GNU General Public License for more details. 12 | // 13 | //You should have received a copy of the GNU General Public License 14 | //along with this program. If not, see . 15 | 16 | 17 | 18 | #ifndef ZERO_PERSISTENCE_PYTHON_H 19 | #define ZERO_PERSISTENCE_PYTHON_H 1 20 | #include 21 | #include 22 | 23 | #include "zero_persistence.h" 24 | using namespace boost::python; 25 | 26 | class ZeroDimensionPersistence { 27 | std::vector function_values; 28 | public: 29 | ZeroDimensionPersistence() { } 30 | ~ZeroDimensionPersistence() { function_values.clear(); } 31 | void add_function_value(boost::python::object index, boost::python::object time, boost::python::object value); 32 | boost::python::list sweep_persistence(); 33 | }; 34 | #endif /* ZERO_PERSISTENCE_PYTHON_H */ 35 | --------------------------------------------------------------------------------