├── .gitignore ├── .gitmodules ├── .idea ├── dictionaries │ └── rhl.xml └── vcs.xml ├── .travis.yml ├── CMakeLists.txt ├── README.md ├── ctl.spec ├── ctl ├── abstract_simplex │ ├── abstract_simplex.hpp │ └── simplex_boundary.hpp ├── cell_complex │ ├── cell_complex.hpp │ ├── complex_boundary.hpp │ └── detail │ │ └── data_wrapper.hpp ├── chain │ ├── chain.hpp │ └── chain_add.hpp ├── cover │ └── cover.hpp ├── ctl.hpp ├── cube │ ├── cube.hpp │ ├── cube_boundary.hpp │ └── detail │ │ └── cube.hpp ├── example │ └── example.hpp ├── finite_field │ └── finite_field.hpp ├── graded_chain_complex │ ├── filtration_iterator.hpp │ ├── graded_boundary.hpp │ ├── graded_cell_complex.hpp │ └── less.hpp ├── hash │ ├── MurmurHash3.hpp │ ├── city.hpp │ └── hash.hpp ├── io │ └── io.hpp ├── matrix │ ├── iterator_property_map.hpp │ ├── matrix.hpp │ └── offset_maps.hpp ├── maximal_cliques │ ├── clique_output_iterator.h │ ├── maximal_cliques.hpp │ ├── test_clique_output_iterator.cpp │ └── test_maximal_cliques.cpp ├── metrics │ └── metric.hpp ├── nbhd_graph │ ├── all_pairs.hpp │ ├── epsilon_search.hpp │ └── nbhd_graph.hpp ├── one_skeleton │ ├── complex_to_graph.hpp │ ├── graph_to_metis.hpp │ └── one_skeleton.hpp ├── parallel │ ├── build_blowup_complex │ │ └── build_blowup_complex.hpp │ ├── chain_complex │ │ └── chain_complex.hpp │ ├── filtration │ │ └── filtration.hpp │ ├── homology │ │ ├── homology.hpp │ │ └── persistence.hpp │ ├── partition_covers │ │ ├── .covers.h.swn │ │ ├── .covers.h.swo │ │ ├── cover_data.hpp │ │ ├── cover_stats.hpp │ │ ├── covers.hpp │ │ └── graph_partition.hpp │ └── utility │ │ └── timer.hpp ├── persistence │ ├── barcodes │ │ └── barcodes.hpp │ ├── compute_barcodes.hpp │ ├── compute_betti.hpp │ ├── persistence.hpp │ ├── persistence_data.hpp │ └── unpair_cells.hpp ├── points │ └── points.hpp ├── product_cell │ ├── iterator_product_boundary.hpp │ ├── iterator_product_cell.hpp │ ├── product_boundary.hpp │ ├── product_cell.hpp │ └── product_cell_less.hpp ├── term │ ├── term.hpp │ ├── term_less.hpp │ └── term_tags.hpp ├── utility │ └── timer.hpp ├── vr │ ├── incremental_complex.hpp │ ├── inductive_complex.hpp │ └── vr.hpp └── weight_data │ ├── weight_data.hpp │ └── weight_functor.hpp ├── dependencies ├── CMakeLists.txt ├── CMakeModules │ ├── CXX11.cmake │ ├── FindANN.cmake │ ├── FindGTest.cmake │ ├── FindMETIS.cmake │ └── FindTBB.cmake └── catch │ └── catch.hpp ├── doc ├── AUTHORS ├── Doxyfile.in ├── LICENSE └── ct.bib ├── man ├── build_clique.1 ├── complex_size.1 ├── concurrent_homology.1 ├── cover_homology.1 ├── duplicate.1 ├── euler.1 ├── gpcover.1 ├── metowgh.1 ├── oneskeleton.1 ├── persistence.1 ├── wghtomet.1 └── write_filtration.1 ├── python ├── CMakeLists.txt ├── ctl.cpp ├── wrap_complex.hpp ├── wrap_cube.hpp ├── wrap_ff.hpp ├── wrap_persistence.hpp ├── wrap_prod_complex.hpp ├── wrap_product.hpp ├── wrap_simplex.hpp ├── wrap_term.hpp └── wrap_vr.hpp ├── tests ├── CMakeLists.txt ├── ctl_test.cpp ├── test_abstract_simplex.cpp ├── test_blowup_tool.cpp ├── test_chain.cpp ├── test_cover_generation.cpp ├── test_cover_tool.cpp ├── test_cube.cpp ├── test_cubical_chain_complex.cpp ├── test_filtration.cpp ├── test_finite_field.cpp ├── test_one_skeleton.cpp ├── test_product_cell.cpp ├── test_simplicial_chain_complex.cpp └── test_vr.cpp ├── tools ├── CMakeLists.txt ├── alpha.cpp ├── betti.cpp ├── build_blobs.cpp ├── cech.cpp ├── clique_tool.cpp ├── complex_size.cpp ├── complex_to_graph_tool.cpp ├── concurrent_homology_tool.cpp ├── cover_homology_tool.cpp ├── euler_tool.cpp ├── gpcover_tool.cpp ├── graph_to_metis_tool.cpp ├── metis_to_graph_tool.cpp ├── ngraph.cpp ├── persistence.cpp ├── phat_tool.cpp ├── sphere.cpp ├── vr.cpp ├── witness.cpp └── write_filtration_tool.cpp └── travis ├── ci_fedora.sh ├── ci_osx.sh └── ci_ubuntu.sh /.gitignore: -------------------------------------------------------------------------------- 1 | CTestTest*.cmake 2 | tests/ctl_test 3 | dependencies/ann 4 | dependencies/gtest 5 | dependencies/metis 6 | dependencies/boost 7 | dependencies/tbb 8 | **/test_multi 9 | deps/gtest 10 | deps/CMakeFiles 11 | deps/Makefile 12 | deps/CMakeCache.txt 13 | distributed/distributed_persistence 14 | ctl/chain_complex/tm 15 | ctl/cube/test_cube 16 | ctl/distributed/distributed_persistence_serial 17 | tools/vr 18 | tools/ngraph 19 | ctl/vr/incremental_test 20 | ctl/vr/test 21 | tools/convert_asc_format 22 | tools/ctl2phat 23 | doc/doxygen/* 24 | tools/convert_asc_format 25 | tools/ctl2phat 26 | doc/doxygen/* 27 | ctl/distributed/distributed_persistence 28 | Doxyfile 29 | tools/distributed_persistence 30 | examples/ 31 | tools/cover_homology 32 | tools/concurrent_homology 33 | tools/write_filtration 34 | cover_test 35 | bin/ 36 | include/ 37 | install_manifest.txt 38 | tools/gpcover 39 | ctl/parallel/build_blowup_complex/blowup_test 40 | ctl/product_cell/test_product_cell 41 | tools/metowgh 42 | tools/oneskeleton 43 | tools/wghtomet 44 | tools/complex_size 45 | tools/persistence 46 | build_clique 47 | duplicate 48 | euler 49 | tf 50 | *.*.swp 51 | test_persistence 52 | test_chain 53 | test_simplex 54 | test_filtration 55 | error 56 | tc 57 | */ts 58 | Makefile 59 | CMakeCache.txt 60 | cmake_install.cmake 61 | *CMakeFiles/ 62 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "pybind11"] 2 | path = dependencies/pybind11 3 | url = https://github.com/pybind/pybind11.git 4 | -------------------------------------------------------------------------------- /.idea/dictionaries/rhl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | # sudo:required is needed for trusty images 4 | sudo: required 5 | dist: trusty 6 | 7 | matrix: 8 | include: 9 | #Disable this until we figure out how to deal with constexpr function bug in gcc 4.9 10 | #- os: linux 11 | # compiler: gcc 12 | # addons: 13 | # apt: 14 | # sources: 15 | # - ubuntu-toolchain-r-test 16 | # packages: 17 | # - g++-4.9 18 | # - libann-dev 19 | # - libboost-all-dev 20 | # - libtbb-dev 21 | # - libmetis-dev 22 | # env: COMPILER=g++-4.9 23 | - os: linux 24 | compiler: gcc 25 | addons: 26 | apt: 27 | sources: 28 | - ubuntu-toolchain-r-test 29 | packages: 30 | - g++-5 31 | - libann-dev 32 | - libboost-all-dev 33 | - libtbb-dev 34 | - libmetis-dev 35 | env: COMPILER=g++-5 36 | - os: linux 37 | compiler: clang 38 | addons: 39 | apt: 40 | sources: 41 | - ubuntu-toolchain-r-test 42 | - llvm-toolchain-precise-3.6 43 | packages: 44 | - clang-3.6 45 | - libann-dev 46 | - libboost-all-dev 47 | - libtbb-dev 48 | - libmetis-dev 49 | env: COMPILER=clang++-3.6 50 | - os: linux 51 | compiler: clang 52 | addons: 53 | apt: 54 | sources: 55 | - ubuntu-toolchain-r-test 56 | - llvm-toolchain-precise-3.7 57 | packages: 58 | - clang-3.7 59 | - libann-dev 60 | - libboost-all-dev 61 | - libtbb-dev 62 | - libmetis-dev 63 | env: COMPILER=clang++-3.7 64 | - os: osx 65 | osx_image: xcode7.3 66 | compiler: clang 67 | env: CCOMPILER='clang' CXXCOMPILER='clang++' 68 | 69 | before_install: 70 | - | 71 | if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then 72 | sudo apt-get install --yes libann-dev 73 | export CC=${COMPILER} CXX=${COMPILER} 74 | elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then 75 | brew tap homebrew/science 76 | brew install cmake mpich tbb boost ann metis 77 | export CC=${CCOMPILER} CXX=${CXXCOMPILER} 78 | fi 79 | 80 | script: 81 | - mkdir build 82 | - cd build 83 | - cmake .. 84 | - make VERBOSE=1 85 | - make test 86 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(ctl CXX) 2 | #stop the whining 3 | cmake_minimum_required(VERSION 2.6.2) 4 | if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) 5 | if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) 6 | cmake_policy(VERSION 2.8.4) 7 | else() 8 | cmake_policy(VERSION 2.6) 9 | endif() 10 | endif() 11 | 12 | 13 | # CTL must be built "out-of-source", so we start by ensuring that the 14 | # source and build directories are different. 15 | if("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}") 16 | message(FATAL_ERROR "In-source build attempted; please clean the CMake cache and then switch to an out-of-source build, e.g., rm CMakeCache.txt && rm -Rf CMakeFiles/ && mkdir build/ && cd build/ && cmake ..") 17 | endif() 18 | 19 | set(CMAKE_BUILD_TYPE Release) 20 | 21 | #Frame pointers are useful for profiling. 22 | #Complaints and pedantry accepted here. 23 | add_definitions("-fno-omit-frame-pointer -pedantic -Wall -ansi -std=c++14") 24 | 25 | #Handle dependencies 26 | set(CTL_DEPS ${CMAKE_SOURCE_DIR}/dependencies) 27 | include( dependencies/CMakeLists.txt) 28 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 29 | include_directories(${CTL_DEPS}) 30 | include_directories(${CTL_DEPS}/pybind11/include/) 31 | #Compile all the tools 32 | add_subdirectory( tools) 33 | 34 | #Compile all the tools 35 | enable_testing() 36 | add_subdirectory( tests) 37 | add_subdirectory( python) 38 | 39 | #All of this is for make install 40 | set(CTL_INCLUDE_INSTALL_DIR ${CMAKE_SOURCE_DIR}/include) 41 | set(CTL_DOC_INSTALL_DIR ${CMAKE_SOURCE_DIR}/doc) 42 | set(CTL_BIN_INSTALL_DIR ${CMAKE_SOURCE_DIR}/bin) 43 | set(CTL_EXAMPLES_INSTALL_DIR ${CMAKE_SOURCE_DIR}/examples) 44 | 45 | install( DIRECTORY ${CMAKE_SOURCE_DIR}/ctl 46 | DESTINATION include 47 | FILES_MATCHING PATTERN "*.h" 48 | PATTERN "CMakeFiles" EXCLUDE) 49 | 50 | install( DIRECTORY ${CMAKE_SOURCE_DIR}/tools 51 | DESTINATION share/ctl/tools 52 | FILES_MATCHING PATTERN "*.cpp" 53 | PATTERN "CMakeLists.txt" 54 | PATTERN "CMakeFiles" EXCLUDE) 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README # 2 | This C++11 library provides a set of generic tools for: 3 | 4 | * Building Neighborhood Graphs 5 | * Building Cellular Complexes 6 | * Computing [persistent] homology over finite fields 7 | * Parallel algorithm(s) for homology 8 | 9 | ## LICENSE ## 10 | * CTL is licensed under the BSD. 11 | * See LICENSE for more info. 12 | 13 | ## DEPENDENCIES ## 14 | 15 | CTL has dependencies. 16 | - boost 17 | - tbb 18 | - metis 19 | - ann (for \epsilon nearest neighbors, we plan to move to a more up to date neighborhood computer) 20 | 21 | We strongly recommend installing them on your system either 22 | as root or with the help of your system administrator via your operating systems 23 | package manager e.g. apt on debian based systems, yum on RHEL systems, or 24 | brew/port/fink on OSX. 25 | 26 | please see .travis.yml for an example of how to to this, and our CI results to clarify is a given commit will build. 27 | 28 | If you wish to install your own dependencies in another way, you can manually edit: 29 | build_dependencies.txt 30 | 31 | If you encounter any issues, make sure to file it: 32 | https://github.com/appliedtopology/ctl/issues 33 | 34 | This list of the dependencies is below and we have annoted 35 | which packages we can auto-help you install locally. 36 | 37 | C++14 compiler (clang or gcc) 38 | Boost 39 | Intel TBB 40 | METIS (make metis) (used for graph partitioning) 41 | ANN (make ann) (used for nearest neighbor querying..) 42 | Doxygen (Optional) 43 | 44 | ## BUILDING ## 45 | 0. You may specify paths to the include/link directories here: 46 | `vim build_dependencies.txt` 47 | 1. CMake will use what you specify, and if you dont it will look on the system 48 | for dependencies (and ideally find them...) 49 | 2. Create makefiles 50 | `mkdir build; cd build; cmake ..` 51 | 3. Compile: (the -j option makes in parallel) 52 | `make -j` 53 | 54 | ### For OS/X Users: ### 55 | If you plan on using the default compiler (clang) 56 | then when installing boost ensure that you use: 57 | brew install boost ---build-from-source --with-c++11 --with-mpi --with-program_options --with-clang --without-single 58 | and after `cmake .` ensure that the compiler chosen is clang via `ccmake .` /usr/bin/c++ 59 | is a good choice. 60 | 61 | Since libstdc++ (GNU C++ STL) and libc++ (Clang C++ STL) are not ABI compatible 62 | one needs to take care to use the correct compilers for libraries linked against. 63 | if boost is compiled with gcc, you cannot use clang to compile CTL and vice versa. 64 | 65 | 66 | ## INSTALL ## 67 | OS/X: 68 | `brew tap appliedtopology/software` 69 | `brew install --HEAD ctl` 70 | 71 | This sticks the headers into the default location on your system and all the tools into the appropriate path/bin directory 72 | 73 | ## SUBMITTING PATCHES ## 74 | Please Do! Accepting Pull Requests via github. 75 | 76 | ### Future ### 77 | We hope to add support for: 78 | * [Persistent] Co-homology 79 | * Zig Zag Persistence 80 | * Multidimensional Persistence 81 | * Tidy Sets 82 | * OpenGL Visualizations 83 | * Bindings to other languages such as Python, MATLAB, and R 84 | 85 | Feel free to fork and help development. Do ask questions! 86 | -------------------------------------------------------------------------------- /ctl.spec: -------------------------------------------------------------------------------- 1 | Name: ctl 2 | Version: 0 3 | Release: noop 4 | Summary: A computational topology library 5 | License: BSD-3 6 | BuildArch: x86_64 7 | Source0: https://github.com/appliedtopology/%{name}/archive/%{commit0}.tar.gz#/%{name}-%{shortcommit0}.tar.gz 8 | BuildRequires: gcc make git zip 9 | BuildRequires: boost-devel 10 | BuildRequires: ann-devel 11 | BuildRequires: tbb-devel 12 | BuildRequires: metis-devel 13 | BuildRequires: doxygen 14 | 15 | BuildRequires: boost 16 | BuildRequires: ann 17 | BuildRequires: tbb 18 | BuildRequires: metis 19 | BuildRequires: doxygen 20 | 21 | %description 22 | A computational topology library 23 | %prep 24 | %autosetup -n %{name}-%{shortcommit0} 25 | 26 | %build 27 | mkdir build 28 | cd build 29 | cmake .. 30 | make %{?_smp_flags} 31 | 32 | %install 33 | make install 34 | 35 | %files 36 | %{_bindir}/* 37 | %{_libdir}/* 38 | 39 | %changelog 40 | -------------------------------------------------------------------------------- /ctl/cell_complex/complex_boundary.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_COMPLEX_BOUNDARY_H 2 | #define CTL_COMPLEX_BOUNDARY_H 3 | /******************************************************************************* 4 | * ********** BSD-3 License **************** 5 | *******************************************************************************/ 6 | //STL 7 | #include // std::iterator, std::input_iterator_tag 8 | 9 | //non exported functionality 10 | namespace ctl{ 11 | namespace detail{ 12 | template< typename Complex_, typename Term_, typename Cell_boundary_> 13 | class _const_boundary_iterator: 14 | public std::iterator< std::input_iterator_tag, 15 | Term_, 16 | std::ptrdiff_t, 17 | const Term_*, 18 | const Term_>{ 19 | typedef _const_boundary_iterator< Complex_, Term_, Cell_boundary_> Self; 20 | typedef Complex_ Complex; 21 | typedef Term_ Term; 22 | typedef Cell_boundary_ Cell_boundary; 23 | 24 | public: 25 | //default 26 | _const_boundary_iterator() {} 27 | 28 | //copy 29 | _const_boundary_iterator( const Self & i): 30 | complex ( i.complex), 31 | next_term( i.next_term), 32 | //future_term( i.future_term), 33 | end_term( i.end_term), 34 | term( i.term) {} 35 | 36 | //move 37 | _const_boundary_iterator( Self && i): 38 | complex ( std::move( i.complex)), 39 | next_term ( std::move( i.next_term)), 40 | end_term ( std::move( i.end_term)), 41 | term( std::move( i.term)) { i.complex = NULL; } 42 | 43 | //begin constructor 44 | _const_boundary_iterator( Complex& _complex, 45 | Cell_boundary & _bd, 46 | const typename Complex::Cell& cell): 47 | complex( &_complex), 48 | next_term ( _bd.begin( cell)), 49 | end_term( _bd.end( cell)){ 50 | _next_term(); 51 | } 52 | //end constructor 53 | _const_boundary_iterator( Complex & _complex): complex( &_complex){ 54 | _end_term(); 55 | } 56 | Self& operator=( const Self& from){ 57 | complex = from.complex; 58 | next_term = from.next_term; 59 | end_term = from.end_term; 60 | term = from.term; 61 | return *this; 62 | } 63 | bool operator==( const Self & i) const { return term == i.term;} 64 | bool operator!=( const Self & i) const { return term != i.term;} 65 | Self& operator++(){ 66 | _next_term(); 67 | return *this; 68 | } 69 | Self operator++(int){ 70 | Self tmp = *this; 71 | _next_term(); 72 | return tmp; 73 | } 74 | Term& operator*(){ return term; } 75 | Term* operator->(){ return &term; } 76 | protected: 77 | void _next_term(){ 78 | if( next_term != end_term){ 79 | term.cell() = complex->find_cell( next_term->cell()); 80 | term.coefficient( next_term->coefficient()); 81 | ++next_term; 82 | return; 83 | } 84 | _end_term(); 85 | } 86 | 87 | void _end_term(){ term.cell() = complex->end(); } 88 | 89 | Complex* complex; 90 | typename Cell_boundary::const_iterator next_term; 91 | typename Cell_boundary::const_iterator end_term; 92 | Term term; 93 | }; //class _const_boundary_iterator 94 | } //detail namespace 95 | } //ctl namespace 96 | 97 | //exported functionality 98 | namespace ctl{ 99 | 100 | template< typename Complex_, 101 | typename Cell_boundary_ = typename Complex_::Cell_boundary, 102 | typename Iterator_ = typename Complex_::iterator > 103 | class Complex_boundary { 104 | typedef Complex_boundary< Complex_> Self; 105 | typedef typename Cell_boundary_::Term Cell_term; 106 | public: 107 | //export types 108 | typedef typename Cell_term::Coefficient Coefficient; 109 | typedef Complex_ Complex; 110 | typedef Cell_boundary_ Cell_boundary; 111 | typedef Iterator_ Iterator; 112 | typedef typename Complex::size_type size_type; 113 | //Complex boundary terms are iterators 114 | typedef typename Cell_term::template 115 | rebind< Iterator, Coefficient>::T Term; 116 | typedef ctl::detail::_const_boundary_iterator< Complex, 117 | Term, 118 | Cell_boundary> 119 | const_iterator; 120 | //copy constructor 121 | Complex_boundary( Complex_boundary & f): _complex( f._complex) {}; 122 | //move constructor, we don't care since we store references 123 | Complex_boundary( Complex_boundary && f): _complex( f._complex) {}; 124 | 125 | Complex_boundary( Complex & complex): _complex( complex) {}; 126 | 127 | const_iterator begin( const typename Term::Cell & c) const { 128 | return const_iterator( _complex, _complex.cell_boundary(), c->first); 129 | } 130 | const_iterator end( const typename Term::Cell & c) const { 131 | return const_iterator( _complex); 132 | } 133 | size_type length( const typename Term::Cell & c) const { 134 | return _complex.cell_boundary().length( c->first); 135 | } 136 | 137 | private: 138 | Complex & _complex; 139 | }; // class Complex_boundary 140 | 141 | } //namespace ctl 142 | 143 | #endif //CTLIB_COMPLEX_BOUNDARY_H 144 | -------------------------------------------------------------------------------- /ctl/cell_complex/detail/data_wrapper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_DATA_WRAPPER_H 2 | #define CTL_DATA_WRAPPER_H 3 | #include 4 | /******************************************************************************* 5 | * BSD-3 6 | ******************************************************************************* 7 | * Copyright (C) Ryan H. Lewis 2014 8 | ******************************************************************************* 9 | * NOTES: 10 | * We use this to associate a single number to every cell opaquely. 11 | *******************************************************************************/ 12 | 13 | namespace ctl { 14 | namespace detail { 15 | 16 | struct Default_data { 17 | constexpr bool operator==( const Default_data & d) const{ return true; } 18 | constexpr bool operator<( const Default_data & d) const { return false; } 19 | }; //class Default_data for complex. 20 | 21 | template< typename Data_> 22 | class Data_wrapper : public Data_ { 23 | private: 24 | typedef Data_wrapper< Data_> Self; 25 | public: 26 | typedef std::size_t Id; 27 | //default 28 | Data_wrapper(): Data_(), id_( 0) {} 29 | //id 30 | Data_wrapper( const Id & tid): Data_(), id_( tid){} 31 | //copy 32 | Data_wrapper( const Data_wrapper & from) : Data_( from), id_( from.id_){} 33 | //move 34 | Data_wrapper( Data_wrapper && from): Data_( std::forward( from)), 35 | id_( std::move( from.id_)){ 36 | } 37 | 38 | Self& operator=( const Self & from){ 39 | Data_::operator=( from); 40 | id_ = from.id_; 41 | return *this; 42 | } 43 | 44 | Self& operator=( Self && from){ 45 | Data_::operator=( from); 46 | id_ = std::move( from.id_); 47 | return *this; 48 | } 49 | 50 | bool operator<( const Self & from) const{ 51 | return Data_::operator<( from); 52 | } 53 | 54 | bool operator==( const Self & b) const { 55 | return (id_ == b.id_) && Data_::operator==( b); 56 | } 57 | bool operator!= (const Self & b) const { return !((*this)==b); } 58 | Id id() const { return id_; } 59 | void id( Id n){ id_ = n; } 60 | private: 61 | Id id_; 62 | }; // class Data_wrapper 63 | 64 | template< typename Stream> 65 | Stream& operator<<( Stream & out, const Default_data & d){ return out; } 66 | template< typename Stream> 67 | Stream& operator<<( Stream & out, const Default_data && d){ return out; } 68 | } //namespace detail 69 | 70 | } //namespace ctl 71 | 72 | #endif //CTL_DEFAULT_WRAPPER 73 | -------------------------------------------------------------------------------- /ctl/cover/cover.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_COVER_HPP 2 | #define CTL_COVER_HPP 3 | #include 4 | #include 5 | #include 6 | 7 | namespace ctl { 8 | template< typename Complex> 9 | decltype(auto) 10 | open_star_cover(const Complex& K, const std::function& f){ 11 | ctl::Simplicial_complex<> nerve; 12 | std::vector< ctl::Abstract_simplex> map_to_nerve; 13 | map_to_nerve.reserve(K.size()); 14 | for(const auto& sigma : K){ 15 | ctl::Abstract_simplex tau; 16 | for( const auto& vtx: sigma.first){ tau.insert(f(vtx)); } 17 | const auto& tau_cell = nerve.insert_closed_cell( tau); 18 | //TODO: These should be references.. 19 | map_to_nerve.emplace_back(tau_cell.first->first); 20 | } 21 | return std::make_pair(nerve, map_to_nerve); 22 | } 23 | 24 | }//end namespace ctl 25 | #endif //CTL_COVER_HPP 26 | -------------------------------------------------------------------------------- /ctl/ctl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_CTL_H 2 | #define CTLIB_CTL_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | #include 9 | #include 10 | 11 | //Abstract Cube 12 | //TODO 13 | 14 | //IO 15 | #include 16 | 17 | //Product Cell 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | //Coefficients 25 | //Finite Fields 26 | #include 27 | 28 | //Chain Complex 29 | #include 30 | #include 31 | 32 | //Weight Data 33 | #include 34 | #include 35 | 36 | 37 | //Term 38 | #include 39 | #include 40 | #include 41 | 42 | //Chain 43 | #include 44 | #include 45 | 46 | //Barcodes 47 | //#include 48 | 49 | //Filtration 50 | #include 51 | #include 52 | #include 53 | 54 | //Graphs & metrics 55 | #include 56 | #include 57 | #include 58 | 59 | //VR 60 | #include 61 | 62 | #include 63 | 64 | //Facilities for extracting the one_skeleton 65 | #include 66 | #include 67 | #include 68 | 69 | //Parallel library (multithreaded) 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | 81 | #include 82 | #include 83 | #include 84 | 85 | //Persistence 86 | #include 87 | #include 88 | #include 89 | #include 90 | 91 | //Not implemented 92 | //#include 93 | 94 | #endif //CTLIB_CTL_H 95 | -------------------------------------------------------------------------------- /ctl/example/example.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_EXAMPLE_H 2 | #define CTLIB_EXAMPLE_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * Release under BSD-3 License See LICENSE 7 | ******************************************************************************* 8 | * NOTES 9 | * 10 | * 11 | *******************************************************************************/ 12 | //STL 13 | //#include < .. > 14 | 15 | //CTL 16 | //#include 17 | 18 | //non-exported functionality 19 | namespace ctl { 20 | namespace detail{} // end namespace detail 21 | } //ctl namespace 22 | 23 | //exported functionality 24 | namespace ctl{} //namespace ctl 25 | 26 | 27 | #endif //CTLIB_EXAMPLE_H 28 | -------------------------------------------------------------------------------- /ctl/graded_chain_complex/filtration_iterator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_FILTRATION_ITERATOR_H 2 | #define CTLIB_FILTRATION_ITERATOR_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | /** 9 | * NOTES: This header is DEPRECATED! 10 | */ 11 | //STL 12 | #include 13 | 14 | //private functionality 15 | //the multiplier gracefully handles reverse iterators. 16 | namespace ctl{ 17 | namespace detail{ 18 | template< typename Iterator, int multiplier> 19 | class _filtration_iterator : 20 | public std::iterator< std::random_access_iterator_tag, 21 | typename Iterator::value_type> { 22 | public: 23 | //Does not matter to be defined since we inherit 24 | typedef typename Iterator::difference_type difference_type; 25 | typedef typename Iterator::value_type value_type; 26 | typedef typename Iterator::pointer pointer; 27 | typedef typename Iterator::reference reference; 28 | typedef std::random_access_iterator_tag iterator_category; 29 | private: 30 | typedef typename Iterator::difference_type diff_type; 31 | typedef _filtration_iterator< Iterator, multiplier> Self; 32 | public: 33 | 34 | //default 35 | _filtration_iterator(): i(), p( 0) {} 36 | //copy 37 | _filtration_iterator( const Self & f): i( f.i), p( f.p) {}; 38 | //move 39 | _filtration_iterator( Self && f): i( std::move( f.i)), 40 | p( std::move(f.p)) {}; 41 | //special 42 | _filtration_iterator( const Iterator & i_, 43 | const std::size_t p_): i( i_), p( p_) {} 44 | Self& operator++(){ 45 | p+=multiplier; i++; 46 | return *this; 47 | } 48 | Self operator++(int){ 49 | Self r( *this); 50 | ++(*this); 51 | return r; 52 | } 53 | Self& operator--(){ 54 | p-=multiplier; i--; 55 | return *this; 56 | } 57 | Self operator--(int){ 58 | Self r( *this); 59 | --(*this); 60 | return r; 61 | } 62 | //deref 63 | pointer operator->() const { return &(*i); } 64 | reference operator*(){ return *i; } 65 | //comparisons 66 | bool operator!=(const Self& r) const { return (i != r.i); } 67 | bool operator==(const Self& r) const { return !operator!=(r); } 68 | bool operator<(const Self& r) const { return (i < r.i); } 69 | bool operator<=(const Self& r) const { return (i <= r.i); } 70 | bool operator>(const Self& r) const { return (i > r.i); } 71 | bool operator>=(const Self& r) const { return (i >= r.i); } 72 | //arithmetic 73 | Self operator+(const diff_type n) const { return Self(i+n, p+n); } 74 | Self operator-(const diff_type n) const { return Self(i-n, p-n); } 75 | diff_type operator-(const Self& a) const { return i-a.i; } 76 | Self& operator=(const Self& r) { i = r.i; p = r.p; return *this; } 77 | Self& operator+=(const difference_type n) { i+=n; p+=n; return *this;} 78 | Self& operator-=(const difference_type n) { i-=n; p-=n; return *this;} 79 | reference operator[](const std::size_t n) const { return *(i+n); } 80 | std::size_t pos() const { return p; } 81 | //the details 82 | private: 83 | Iterator i; 84 | std::size_t p; 85 | }; //class _filtration_iterator 86 | } //namespace detail 87 | } //namespace ctl 88 | #endif //CTLIB_FILTRATION_ITERATOR_H 89 | -------------------------------------------------------------------------------- /ctl/graded_chain_complex/less.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_FILTRATION_LESS_H 2 | #define CTLIB_FILTRATION_LESS_H 3 | /******************************************************************************* 4 | ******************************************************************************* 5 | * Copyright (C) Ryan H. Lewis 2014 6 | ******************************************************************************* 7 | * ********** BSD-3 License **************** 8 | *******************************************************************************/ 9 | //exported functionality 10 | namespace ctl{ 11 | 12 | struct Id_less{ 13 | constexpr Id_less(){} 14 | template< typename Cell_iterator> 15 | bool operator()( const Cell_iterator & a, const Cell_iterator & b) const { 16 | return a->second.id() < b->second.id(); 17 | } 18 | }; //struct Id_less 19 | 20 | //Order by data, break ties by cell order 21 | struct Cell_less{ 22 | constexpr Cell_less(){} 23 | 24 | template< typename Cell_iterator> 25 | bool operator()( const Cell_iterator & a, const Cell_iterator & b) const { 26 | return (a->second < b->second) || 27 | (!(b->second < a->second) && (a->first < b->first)); 28 | } 29 | }; //struct Cell_less 30 | 31 | } //namespace ctl 32 | 33 | #endif //CTLIB_FILTRATION_LESS_H 34 | -------------------------------------------------------------------------------- /ctl/hash/hash.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_HASH_H 2 | #define CTLIB_HASH_H 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2014 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | *******************************************************************************/ 24 | 25 | #define CTL_USE_CITY 26 | 27 | //STL 28 | #include 29 | 30 | //CTL 31 | namespace ctl{ 32 | namespace hash{ 33 | #include 34 | #include 35 | } //end namespace hash 36 | } //end namespace ctl 37 | //non-exported functionality 38 | namespace ctl{ 39 | namespace detail{ 40 | namespace cth = ctl::hash; 41 | template< typename Container> 42 | inline 43 | std::size_t murmur3_hash( const Container & key, std::false_type){ 44 | typedef typename Container::value_type T; 45 | std::size_t out; 46 | //MurmurHash3_x86_32 47 | //MurmurHash3_x86_128 48 | cth::MurmurHash3_x64_128 ( (const char*)&(*(key.begin())), 49 | sizeof(T)*key.size(), key.size(), &out ); 50 | return out; 51 | } 52 | 53 | template< typename T> 54 | inline std::size_t murmur3_hash( const T & t, std::true_type){ 55 | std::size_t out; 56 | cth::MurmurHash3_x86_128( (const char*)&t, sizeof(T), 1, &out); 57 | return out; 58 | } 59 | 60 | template< typename Container> 61 | inline std::size_t city_hash( const Container & key, std::false_type){ 62 | typedef typename Container::value_type T; 63 | return cth::CityHash64WithSeed( (const char*)&(*(key.begin())), 64 | sizeof(T)*key.size(),key.size()); 65 | } 66 | 67 | template< typename T> 68 | inline std::size_t city_hash( const T & t, std::true_type){ 69 | return cth::CityHash64WithSeed( (const char*)&(t), 70 | sizeof(T),1); 71 | } 72 | 73 | template< typename T> 74 | inline std::size_t pjw_hash( const T & key){ 75 | std::size_t h, g; 76 | h = 0; 77 | for( auto i : key){ 78 | h = (h << 4) + i; 79 | if ((g = h & 0xf0000000)) { 80 | h = h^(g >> 24); 81 | h = h^g; 82 | } 83 | } 84 | return h; 85 | } 86 | template< typename T> 87 | inline std::size_t jenkins_hash( const T & key){ 88 | std::size_t hash=0; 89 | for(auto i : key){ 90 | hash += i; 91 | hash += (hash << 10); 92 | hash ^= (hash >> 6); 93 | } 94 | hash += (hash << 3); 95 | hash ^= (hash >> 11); 96 | hash += (hash << 15); 97 | return hash; 98 | } 99 | 100 | } //detail namespace 101 | } //ctl namespace 102 | 103 | namespace ctl { 104 | 105 | template< typename T> 106 | std::size_t hash_function( const T & key){ 107 | #ifdef CTL_USE_MURMUR 108 | return detail::murmur3_hash( key, std::is_integral< T>()); 109 | #elif defined( CTL_USE_CITY) 110 | return detail::city_hash( key, std::is_integral< T>()); 111 | #elif defined( CTL_USE_JENKINS) 112 | return detail::jenkins_hash( key); 113 | #else 114 | return detail::pjw_hash( key); 115 | #endif 116 | } 117 | 118 | template< typename T> 119 | struct Hash{ 120 | std::size_t operator()( const T & key) const{ 121 | return hash_function( key); 122 | } 123 | }; //class Hash 124 | } //namespace ctl 125 | #endif //CTLIB_HASH_H 126 | -------------------------------------------------------------------------------- /ctl/io/io.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_IO_H 2 | #define CTLIB_IO_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2011 5 | ******************************************************************************* 6 | * Released under BSD-3 License. See LICENSE 7 | *******************************************************************************/ 8 | //STL 9 | #include 10 | #include 11 | 12 | namespace ctl{ 13 | constexpr char delta[] = "\u2202"; 14 | constexpr char sigma[] = "\u03C3"; 15 | constexpr char tau[] = "\u1D6D5"; 16 | constexpr char otimes[] = "\u2297"; 17 | constexpr char oplus[] = "\u2295"; 18 | 19 | struct identity { 20 | template 21 | inline constexpr auto operator()(U&& v) const noexcept 22 | -> decltype(std::forward(v)) 23 | { 24 | return std::forward(v); 25 | } 26 | template 27 | inline constexpr U& operator[](U& v) const noexcept { return v; } 28 | 29 | template 30 | constexpr auto operator()(X && y, U&& v) const noexcept 31 | -> decltype(std::forward(v)) 32 | { 33 | return std::forward(v); 34 | } 35 | 36 | template 37 | constexpr bool operator()(Cell && c, U&& v, bool f) const noexcept { 38 | return true; 39 | } 40 | 41 | }; 42 | 43 | template< typename Stream> 44 | bool open_file( Stream & in, const char* file_name){ 45 | in.open( file_name); 46 | return in.is_open(); 47 | } 48 | template< typename Stream> 49 | void close_file( Stream & in){ in.close(); } 50 | 51 | template< typename Stream> 52 | bool get_line( Stream & in, std::string & line, std::size_t & line_num){ 53 | while( in.good()){ 54 | std::getline( in, line); 55 | ++line_num; 56 | switch( line[0]){ 57 | case '#': 58 | case '%': 59 | case '\0': 60 | break; 61 | default: 62 | return true; 63 | } 64 | } 65 | return false; 66 | } 67 | 68 | } //namespace ctl 69 | 70 | #endif //CTLIB_IO_H 71 | -------------------------------------------------------------------------------- /ctl/matrix/matrix.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_MATRIX_H 2 | #define CTL_MATRIX_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace ctl { 9 | 10 | /** 11 | * @brief Defines a Sparse matrix using the Dictionary of Keys 12 | * Storage type 13 | * 14 | * It stoes a ctl::Chain< ctl::Term< Coefficient, Index> > 15 | * where index references the row or column index. 16 | * 17 | * @tparam C 18 | * @tparam T 19 | */ 20 | template< typename Coeff, typename Cell=std::size_t> 21 | using Sparse_matrix = std::vector< ctl::Chain< ctl::Term< Cell, Coeff> > >; 22 | 23 | template< typename Iterator> 24 | using Offset_map = ctl::Pos_offset_map< Iterator>; 25 | 26 | template< typename Coeff, typename Offset_map, typename Cell=std::size_t> 27 | using Sparse_matrix_map = ctl::iterator_property_map< typename Sparse_matrix< Coeff, Cell>::iterator, 28 | Offset_map, 29 | typename Sparse_matrix< Coeff,Cell>::value_type, 30 | typename Sparse_matrix< Coeff,Cell>::value_type&>; 31 | } 32 | 33 | #endif //CTL_MATRIX_H 34 | -------------------------------------------------------------------------------- /ctl/maximal_cliques/clique_output_iterator.h: -------------------------------------------------------------------------------- 1 | // clique_output_iterator.h 2 | // Gabe Weaver 3 | // August 20, 2008 4 | // 5 | // Exports Clique_output_iterator class 6 | 7 | // Class: Clique_output_iterator 8 | // 9 | // Simply couts the set representing the clique 10 | 11 | #ifndef _CTL_CLIQUE_OUTPUT_ITERATOR_H_ 12 | #define _CTL_CLIQUE_OUTPUT_ITERATOR_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace ctl { 20 | 21 | template< class Clique_> 22 | class Clique_output_iterator : 23 | public std::iterator< std::output_iterator_tag, 24 | Clique_, 25 | void, 26 | void, 27 | void> { 28 | public: 29 | Clique_output_iterator() : num_cliques_( 0) {} 30 | Clique_output_iterator& 31 | operator=( const Clique_& clique) 32 | { 33 | ++num_cliques_; 34 | typename Clique_::const_iterator clique_iter; 35 | for ( clique_iter = clique.begin(); 36 | clique_iter != clique.end(); 37 | clique_iter++) { 38 | std::cout << (*clique_iter) << " "; 39 | } 40 | std::cout << std::endl; 41 | return *this; 42 | } 43 | 44 | Clique_output_iterator& operator*() { return *this; } 45 | Clique_output_iterator& operator++() { return *this; } 46 | Clique_output_iterator& operator++( int) { return *this; } 47 | int num() { 48 | return num_cliques_; 49 | } 50 | private: 51 | int num_cliques_; 52 | }; 53 | 54 | } // namespace ctl 55 | 56 | #endif // _CTL_CLIQUE_OUTPUT_ITERATOR_H_ 57 | -------------------------------------------------------------------------------- /ctl/maximal_cliques/test_clique_output_iterator.cpp: -------------------------------------------------------------------------------- 1 | // test_clique_output_iterator.C 2 | // Gabe Weaver 3 | // August 19, 2008 4 | 5 | #include 6 | #include "clique_output_iterator.h" 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | typedef std::set Clique; 11 | typedef std::set< Clique > CliqueSet; 12 | 13 | CliqueSet cliques; 14 | CliqueSet::iterator clique_iter; 15 | 16 | int c1[4] = { 22, 33, 44, 55 }; 17 | int c2[6] = { 5, 10, 15, 20, 25, 30 }; 18 | 19 | Clique clique1(c1, c1 + 4); 20 | Clique clique2(c2, c2 + 6); 21 | 22 | cliques.insert(clique1); 23 | cliques.insert(clique2); 24 | 25 | ctl::Clique_output_iterator out; 26 | 27 | for (clique_iter = cliques.begin(); 28 | clique_iter != cliques.end(); 29 | clique_iter++) { 30 | Clique clique = (Clique)(*clique_iter); 31 | *out++ = clique; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ctl/maximal_cliques/test_maximal_cliques.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * Release under BSD-3 License See LICENSE 5 | ******************************************************************************* 6 | * NOTES 7 | * Based on original implementation by Gabe Weaver 8 | *******************************************************************************/ 9 | 10 | // Standard & STL 11 | #include // ifstream, cerr 12 | 13 | // BGL 14 | #include 15 | 16 | // CTL 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | int main(int argc, char *argv[]) { 25 | typedef boost::graph_traits< ctl::Nbhd_graph> graph_traits; 26 | typedef graph_traits::vertex_descriptor vertex_descriptor; 27 | typedef std::vector< vertex_descriptor> Vector; 28 | 29 | // Parse command line 30 | if( argc < 2) { 31 | std::cerr << argv[0] << " graph" << std::endl; 32 | std::exit(1); 33 | } 34 | 35 | // Establish input stream 36 | std::ifstream in; 37 | ctl::open_file( in, argv[1]); 38 | 39 | // Read the graph 40 | ctl::Nbhd_graph graph; 41 | in >> graph; 42 | 43 | // Setup the output iterator 44 | ctl::Clique_output_iterator< Vector> out; 45 | 46 | // Count number of maximal cliques 47 | ctl::Timer timer; 48 | timer.start(); 49 | ctl::maximal_cliques(graph, out); 50 | std::cout << out.num() << " cliques in " << timer.get() << " seconds" << 51 | std::endl; 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /ctl/metrics/metric.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_LP_H 2 | #define CTLIB_LP_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | //exported functionality 9 | namespace ctl{ 10 | 11 | template< typename Point, int p=2> 12 | double lp( const Point & a, const Point & b) { 13 | //typedef typename Point::const_iterator iterator; 14 | double dist=0; 15 | auto i = a.begin(); 16 | for( auto j = b.begin(); i != a.end(); ++i, ++j){ 17 | dist += std::pow((*i)-(*j),p); 18 | } 19 | return dist; 20 | } 21 | 22 | template< typename Point> 23 | double hamming( const Point & a, const Point & b) { 24 | //typedef typename Point::const_iterator iterator; 25 | double dist=0; 26 | auto i = a.begin(); 27 | for( auto j = b.begin(); i != a.end(); ++i, ++j){ 28 | dist += (*i==*j); 29 | } 30 | return dist; 31 | } 32 | 33 | } //namespace ctl 34 | 35 | #endif //CTLIB_LP_H 36 | -------------------------------------------------------------------------------- /ctl/nbhd_graph/all_pairs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_ALL_PAIRS_H 2 | #define CTL_ALL_PAIRS_H 3 | /******************************************************************************* 4 | Copyright (C) Ryan H. Lewis 2014 5 | ********** BSD-3 License **************** 6 | ******************************************************************************* 7 | * NOTES 8 | * We use the all pairs approach to constuct a graph. 9 | * 10 | *******************************************************************************/ 11 | 12 | //STL 13 | #include 14 | #include 15 | 16 | //BOOST 17 | #include 18 | 19 | namespace ctl{ 20 | namespace all_pairs{ 21 | template< typename It1, typename It2> 22 | double lp( It1 begin1, It1 end1, It2 begin2){ 23 | double r = 0.0; 24 | for( ; begin1 != end1; ++begin1, ++begin2){ 25 | double v = (*begin1 - *begin2); 26 | r += v*v; 27 | } 28 | return r; 29 | } 30 | 31 | 32 | 33 | template 34 | void construct_graph( const Points& points, 35 | const double epsilon, 36 | Graph& graph) { 37 | typedef typename boost::graph_traits graph_traits; 38 | typedef typename graph_traits::vertex_iterator vertex_iterator; 39 | typedef typename boost::graph_traits< Graph>::vertex_descriptor vertex_descriptor; 40 | typedef typename boost::property_map< Graph, 41 | boost::vertex_name_t>::type name_map_t; 42 | typedef typename boost::property_traits< name_map_t>::value_type vertex_name_t; 43 | typedef std::unordered_map< vertex_name_t, vertex_descriptor> Name_to_descriptor_map; 44 | 45 | name_map_t name_map = boost::get( boost::vertex_name, graph); 46 | Name_to_descriptor_map descriptor( points.size()); 47 | 48 | // add vertices 49 | for( std::size_t i = 0; i < points.size(); ++i) { 50 | vertex_descriptor v_descriptor = boost::add_vertex( graph); 51 | name_map[ v_descriptor] = i; 52 | descriptor.emplace( i, v_descriptor); 53 | } 54 | 55 | // add edges 56 | vertex_iterator vi, vj, vlast; 57 | double epsilon_squared = epsilon*epsilon; 58 | for ( std::tie( vi, vlast) = boost::vertices( graph); vi != vlast; ++vi) { 59 | for ( std::tie( vj, vlast) = boost::vertices (graph); vj != vi; ++vj) { 60 | 61 | if( lp(points.begin(name_map[*vi]), 62 | points.end(name_map[*vi]), 63 | points.begin(name_map[*vj])) < epsilon_squared){ 64 | boost::add_edge(*vi, *vj, graph); 65 | } 66 | } 67 | } 68 | } 69 | } //end namespace all_pairs 70 | } //end namespace CTL 71 | 72 | 73 | #endif //CTL_ALL_PAIRS_H 74 | -------------------------------------------------------------------------------- /ctl/one_skeleton/graph_to_metis.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_GRAPH_TO_METIS_H 2 | #define CTL_GRAPH_TO_METIS_H 3 | /******************************************************************************* 4 | Copyright (C) Ryan H. Lewis 2011 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | ******************************************************************************/ 8 | // STL 9 | #include // not sure if algorithm,sstream are necessary yet 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | // BGL 17 | #include 18 | #include 19 | #include 20 | 21 | // PROJECT 22 | #include 23 | #include 24 | 25 | namespace ctl { 26 | 27 | template 28 | void write_metis( OutputStream & out, 29 | offsets_t & offsets, 30 | neighbors_t & neighbors){ 31 | int num_vertices = offsets.size() - 1; 32 | int num_edges = neighbors.size()/2.0; 33 | out << num_vertices << " " << num_edges << " " << "0" << std::endl; 34 | for (int i = 0; i < num_vertices; ++i){ 35 | for (int j = offsets[i]; j < offsets[i+1]; ++j){ 36 | out << neighbors[j] << " "; 37 | } 38 | out << std::endl; 39 | } 40 | } 41 | 42 | 43 | template< typename Graph, 44 | typename Index_to_vertex_map, 45 | typename Vertex_to_index_map, 46 | typename Vector> 47 | void graph_to_metis( Graph & graph, 48 | Vector & offsets, 49 | Vector & neighbors, 50 | Vertex_to_index_map & vertex_to_index, 51 | Index_to_vertex_map & index_to_vertex){ 52 | typedef typename boost::graph_traits< Graph> graph_traits; 53 | typedef typename graph_traits::vertex_iterator Vertex_iterator; 54 | typedef typename graph_traits::vertices_size_type Vertices_size_t; 55 | 56 | typedef typename boost::property_map< Graph, 57 | boost::vertex_name_t>::type Name_map; 58 | 59 | typedef typename boost::property_traits< Name_map>::value_type 60 | Vertex_name; 61 | typedef typename boost::graph_traits::adjacency_iterator 62 | Adjacency_iterator; 63 | typedef typename std::pair Pair; 64 | //typedef typename Vertex_to_index_map::value_type Index; 65 | Name_map name_map = boost::get( boost::vertex_name, graph); 66 | 67 | Vertex_iterator vi, vlast; 68 | //CSR calls each vertex 1 ... n 69 | Vertices_size_t count = 0; 70 | for (std::tie( vi, vlast) = vertices( graph); vi != vlast; ++vi, ++count){ 71 | Vertex_name name = boost::get( name_map, *vi); 72 | vertex_to_index[ name] = count; 73 | index_to_vertex[ count] = name; 74 | } 75 | //CSR stores all edges in a length 2*numedges array, (it stores each 76 | //edge twice (u,v) and (v,u) 77 | //edges (i,j) are in the range 78 | //neighbors[offsets[i]] ... neighbors[offsets[i+1]-1] 79 | offsets[ 0] = 0; 80 | size_t index = 0; 81 | for (std::tie(vi, vlast) = vertices( graph); vi != vlast; ++vi){ 82 | Pair edge = boost::adjacent_vertices(*vi, graph); 83 | Vector local; 84 | //assumes this dist() makes sense.. 85 | local.reserve( std::distance( edge.first, edge.second)); 86 | for ( Adjacency_iterator u = edge.first; 87 | u != edge.second; u++){ 88 | Vertex_name v_name = boost::get( name_map,*u); 89 | local.push_back( vertex_to_index[ v_name]+1); 90 | } 91 | //why not keep things sorted..? 92 | std::sort( local.begin(), local.end()); 93 | std::copy( local.begin(), local.end(), 94 | neighbors.begin()+offsets[ index++]); 95 | offsets[ index] = offsets[index-1] + 96 | std::distance( edge.first, edge.second); 97 | } 98 | } 99 | } 100 | #endif // CTL_GRAPH_TO_METIS_H 101 | -------------------------------------------------------------------------------- /ctl/parallel/chain_complex/chain_complex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_CONCURRENT_CELL_MAP_H 2 | #define CTLIB_CONCURRENT_CELL_MAP_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | /********************* 9 | * April 5th, 2014 10 | * Notes: presently we wrap the std::unordered_map a.k.a Map type. 11 | * We fail to have perfect hashing, and we have collisions between 12 | * cells of various different dimensions. 13 | * A relatively easy optimization to explore is to have something like 14 | * vector< Map> where array element i stores cells of dimension i. 15 | * Aside from certainly having less collisions, 16 | * this has the benefit that the skeletal filtration will now be available with 17 | * zero extra work after complex construction. 18 | * We don't even need to worry about resizing time, since, copying a map is done 19 | * via a swap of ~4 pointers, and in c++11 they are moves. 20 | * Also this only happens at most O(log(d)) or something.. 21 | * the only thing to be careful of is the begin() and end() needs to be the 22 | * original begin() and end() iterators concatenated together. 23 | * This is somewhat frustrating because the naive implementation will require a 24 | * 5x space bloat for each iterator, so less iterators fit on a cache line. 25 | * A massive sort might have 5x more cache misses, for example, and 26 | * the chains we store for persistence will have more stuff in them. 27 | * We would save space by forcing a single hash table to hash cells of different 28 | * dimensions to different places. 29 | * This also makes iterators 30 | * invalid less often then they were before. 31 | * In particular, iterators are only invalidated in one dimension at a time, 32 | * AND rehashing will be marginally less expensive. 33 | * begin()/end() would be overloaded to take a dimension as well. 34 | **********************/ 35 | //STL 36 | #include 37 | #include 38 | #include 39 | 40 | //CTL 41 | #include 42 | #include 43 | #include 44 | 45 | #include 46 | 47 | //exported functionality 48 | namespace ctl{ 49 | namespace parallel { 50 | template< typename Boundary_, 51 | typename Data_ = ctl::detail::Default_data, 52 | typename Hash_ = ctl::Hash< typename Boundary_::Cell_> > 53 | using Cell_complex = ctl::Cell_complex< Boundary_, 54 | Data_, Hash_, true>; 55 | } //namespace parallel 56 | } //namespace ctl 57 | 58 | #endif //CTL_CONCURRENT_CHAIN_COMPLEX_MAP_H 59 | -------------------------------------------------------------------------------- /ctl/parallel/filtration/filtration.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_CONCURRENT_FILTRATION_H 2 | #define CTLIB_CONCURRENT_FILTRATION_H 3 | /******************************************************************************* 4 | ******************************************************************************* 5 | * Copyright (C) Ryan H. Lewis 2014 6 | ******************************************************************************* 7 | * ********** BSD-3 License **************** 8 | *******************************************************************************/ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace ctl{ 18 | //non-exported functionality 19 | namespace _filtration{ 20 | } //anonymous namespace 21 | 22 | namespace parallel{ 23 | template< typename Complex_, 24 | typename Less_ = ctl::Cell_less, 25 | typename Iterator_ = typename Complex_::iterator, 26 | typename Vector_ = tbb::concurrent_vector< Iterator_> > 27 | class Filtration { 28 | public: 29 | typedef Complex_ Complex; 30 | typedef Less_ Less; 31 | private: 32 | typedef Vector_ Vector; 33 | typedef typename Vector::iterator _viterator; 34 | typedef typename Vector::const_iterator _vciterator; 35 | typedef typename Vector::reverse_iterator _vriterator; 36 | typedef typename Vector::const_reverse_iterator _vcriterator; 37 | typedef typename Complex::Cell_boundary Cell_boundary; 38 | typedef typename Cell_boundary::Term Cell_term; 39 | typedef typename Cell_term::Coefficient Coefficient; 40 | 41 | public: 42 | /* 43 | typedef typename ctl::detail::_filtration_iterator< _viterator, 1> 44 | iterator; 45 | typedef typename ctl::detail::_filtration_iterator< _vciterator, 1> 46 | const_iterator; 47 | typedef typename ctl::detail::_filtration_iterator< _viterator, -1> 48 | reverse_iterator; 49 | typedef typename ctl::detail::_filtration_iterator< _vciterator, -1> 50 | const_reverse_iterator; 51 | */ 52 | typedef typename Vector::iterator iterator; 53 | typedef typename Vector::const_iterator const_iterator; 54 | typedef typename Vector::reverse_iterator reverse_iterator; 55 | typedef typename Vector::const_reverse_iterator const_reverse_iterator; 56 | 57 | //A graded term! iterators themselves can represent grading via address. 58 | typedef typename Cell_term::template 59 | rebind< iterator, Coefficient>::T Term; 60 | typedef typename Vector::value_type value_type; 61 | typedef typename Vector::reference reference; 62 | typedef typename Vector::const_reference const_reference; 63 | private: 64 | //just to make typing below easier 65 | typedef iterator it; 66 | typedef const_iterator cit; 67 | typedef const_reverse_iterator crit; 68 | typedef reverse_iterator rit; 69 | public: 70 | Filtration( const Filtration & f): 71 | filtration_( f), complex_( f.complex_) {} 72 | Filtration( const Filtration && f): 73 | filtration_( std::move( f)), complex_( std::move( f.complex_)) {} 74 | //these are constructors used to hack together a filtration 75 | Filtration( Complex & c, bool flag): 76 | filtration_( c.size()), complex_( c) {} 77 | Filtration( Complex & c, std::size_t size, bool flag): 78 | filtration_( size), complex_( c) {} 79 | //this is a default filtration 80 | Filtration( Complex & c): filtration_( c.size()), complex_( c){ 81 | std::size_t pos = 0; 82 | for( auto i= c.begin(); i != c.end(); ++i, ++pos){ 83 | filtration_[ pos] = i; 84 | } 85 | Less less; 86 | tbb::parallel_sort( filtration_.begin(), filtration_.end(), less); 87 | } 88 | 89 | reference operator[] (std::size_t n) { return filtration_[ n]; } 90 | const_reference operator[] (std::size_t n) const { 91 | return filtration_[ n]; 92 | } 93 | 94 | //used typedefs above since the names were getting to long 95 | it begin() { return filtration_.begin(); } 96 | it end() { return filtration_.end(); } 97 | 98 | cit begin() const { return filtration_.begin(); } 99 | cit end() const { return filtration_.end(); } 100 | 101 | cit cbegin() const { return filtration_.begin(); } 102 | cit cend() const { return filtration_.end(); } 103 | 104 | rit rbegin() { return filtration_.rbegin(); } 105 | rit rend() { return filtration_.rend(); } 106 | 107 | crit rbegin() const { return filtration_.rbegin(); } 108 | crit rend() const { return filtration_.rend(); } 109 | 110 | Complex& complex() const { return complex_; } 111 | 112 | std::size_t size() const { return filtration_.size(); } 113 | private: 114 | Vector filtration_; 115 | Complex& complex_; 116 | }; //class Filtration 117 | } //namespace parallel 118 | } //namespace ct 119 | #endif //CTLIB_CONCURRENT_FILTRATION_H 120 | -------------------------------------------------------------------------------- /ctl/parallel/partition_covers/.covers.h.swn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appliedtopology/ctl/b610fa4a9afc439b071457dd0c9d1a823ac1537a/ctl/parallel/partition_covers/.covers.h.swn -------------------------------------------------------------------------------- /ctl/parallel/partition_covers/.covers.h.swo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appliedtopology/ctl/b610fa4a9afc439b071457dd0c9d1a823ac1537a/ctl/parallel/partition_covers/.covers.h.swo -------------------------------------------------------------------------------- /ctl/parallel/partition_covers/cover_data.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CTL_COVER_DATA_H 2 | #define _CTL_COVER_DATA_H 3 | /******************************************************************************* 4 | ******************************************************************************* 5 | * Copyright (C) Ryan H. Lewis 2011 6 | ******************************************************************************* 7 | * ********** BSD-3 License **************** 8 | *******************************************************************************/ 9 | 10 | #include 11 | 12 | namespace ctl{ 13 | namespace parallel{ 14 | class Nerve_data 15 | { 16 | private: 17 | typedef Nerve_data Self; 18 | typedef tbb::atomic< size_t> Count_t; 19 | public: 20 | // default constructor 21 | Nerve_data( size_t count = 0) 22 | : count_(){count_ = count;} 23 | 24 | // copy constructor 25 | Nerve_data( const Nerve_data &from) : count_( from.count_) {} 26 | 27 | // assignment operator 28 | Nerve_data& operator=( const Nerve_data& from) 29 | { 30 | count_ = from.count_; 31 | return *this; 32 | } 33 | //dont enforce anything extra on order 34 | inline const bool operator<( const Self & f) const { return false; } 35 | 36 | void pp() { count_++;} 37 | Count_t & count() { return count_; } 38 | const Count_t count() const { return count_; } 39 | 40 | private: 41 | Count_t count_; 42 | }; // class Nerve_data 43 | 44 | template< typename Data_> 45 | class Cover_data { 46 | private: 47 | typedef Cover_data< Data_> Self; 48 | public: 49 | typedef Data_ Data1; 50 | 51 | // default constructor 52 | Cover_data( const Data1& data = Data1()) 53 | : data_( data){} 54 | 55 | // copy constructor 56 | Cover_data( const Cover_data &from): data_( from.data_){} 57 | 58 | // assignment operator 59 | Cover_data& operator=( const Cover_data& from) { 60 | data_ = from.data_; 61 | return *this; 62 | } 63 | 64 | //dont enforce covering relation.. 65 | constexpr bool operator<( const Self & f) const { return false; } 66 | 67 | Data1& data() { return data_; } 68 | const Data1& data() const { return data_; } 69 | 70 | private: 71 | Data_ data_; 72 | }; // class Cover_data 73 | 74 | template< typename Data> 75 | struct Get_cover : 76 | public std::unary_function< Data &, 77 | typename Data::Data1::value_type::first_type &> 78 | { 79 | typedef typename Data::Data1 Nerve_iterator; 80 | typedef typename Nerve_iterator::value_type::first_type Cell; 81 | Get_cover(){} 82 | Cell& operator()( Data & data) const{ 83 | return data.data()->first; 84 | } 85 | 86 | const Cell& operator()( const Data & data) const{ 87 | return data.data()->first; 88 | } 89 | }; 90 | 91 | template< typename Stream> 92 | Stream& operator<<( Stream & out, const ctl::parallel::Nerve_data & d){ 93 | out << d.count(); 94 | return out; 95 | } 96 | template< typename Stream> 97 | Stream& operator<<( Stream & out, ctl::parallel::Nerve_data && d){ 98 | out << d; 99 | return out; 100 | } 101 | 102 | 103 | 104 | template< typename Stream, typename Data> 105 | Stream& operator<<( Stream & out, const ctl::parallel::Cover_data< Data> & d){ 106 | return out; 107 | } 108 | template< typename Stream, typename Data> 109 | Stream& operator<<( Stream & out, ctl::parallel::Cover_data< Data> && d){ 110 | out << d; 111 | return out; 112 | } 113 | 114 | 115 | } // namespace parallel 116 | } //namespace ctl 117 | #endif // _CTL_COVER_DATA_H 118 | -------------------------------------------------------------------------------- /ctl/parallel/partition_covers/graph_partition.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CTL_METIS_H_ 2 | #define _CTL_METIS_H_ 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2011 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * 26 | * 1. Redistributions of source code must retain the above copyright notice, 27 | * this list of conditions and the following disclaimer. 28 | * 29 | * 2. Redistributions in binary form must reproduce the above copyright notice, 30 | * this list of conditions and the following disclaimer in the documentation 31 | * and/or other materials provided with the distribution. 32 | * 33 | * 3. Neither the name of the copyright holder nor the names of its contributors 34 | * may be used to endorse or promote products derived from this software without 35 | * specific prior written permission. 36 | * 37 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | * POSSIBILITY OF SUCH DAMAGE. 48 | ******************************************************************************** 49 | *******************************************************************************/ 50 | 51 | //TIMER 52 | #include 53 | #include 54 | 55 | //STL 56 | #include //max & min_element 57 | 58 | //METIS 59 | extern "C" { 60 | #include 61 | } 62 | 63 | namespace ctl { 64 | namespace parallel{ 65 | template< typename Vector> 66 | void metis( Vector & xadj, 67 | Vector & adjncy, 68 | Vector & part, 69 | idx_t & edgecut, 70 | idx_t & num_vertices, 71 | idx_t num_parts){ 72 | idx_t ncon = 1; 73 | //hopefully updated to v5.0 spec 74 | METIS_PartGraphRecursive( &num_vertices, 75 | &ncon, //no idea what this is for, but the manual 76 | //suggests making it = 2. 77 | &xadj[0], &adjncy[0], 78 | NULL, NULL, NULL, 79 | &num_parts, 80 | NULL, NULL, NULL, 81 | &edgecut, &part[0]); 82 | } 83 | 84 | template< typename Complex, 85 | typename Cover_complex, 86 | typename Index_to_vertex_map, 87 | typename Vertex_to_part_map, 88 | typename Vertex_to_nerve_map> 89 | void metis_to_complex( Complex & complex, 90 | Cover_complex & nerve, 91 | const Index_to_vertex_map & index_to_vertex, 92 | Vertex_to_nerve_map & vertex_to_nerve, 93 | const Vertex_to_part_map & part){ 94 | 95 | typedef typename Complex::Cell Cell; 96 | //typedef typename Complex::iterator Complex_iterator; 97 | typedef typename Cover_complex::Cell Nerve_cell; 98 | typedef typename Cover_complex::iterator Nerve_iterator; 99 | typedef typename Index_to_vertex_map::const_iterator Index_iterator; 100 | for( Index_iterator i = index_to_vertex.begin(); 101 | i < index_to_vertex.end(); ++i){ 102 | const int j = std::distance( index_to_vertex.begin(), i); 103 | Cell cell = { (std::size_t)*i }; 104 | Nerve_cell part_cell = { (std::size_t)part[ j] }; 105 | Nerve_iterator iterator = nerve.find_cell( part_cell); 106 | vertex_to_nerve.insert( make_pair( *i, iterator) ); 107 | complex.find_cell( cell)->second.data() = iterator; 108 | } 109 | } 110 | 111 | } //end namespace parallel 112 | } //end namespace ctl 113 | #endif // _CTL_COVERS_H 114 | -------------------------------------------------------------------------------- /ctl/parallel/utility/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_TBB_TIMER_H 2 | #define CTLIB_TBB_TIMER_H 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2014 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * 26 | * 1. Redistributions of source code must retain the above copyright notice, 27 | * this list of conditions and the following disclaimer. 28 | * 29 | * 2. Redistributions in binary form must reproduce the above copyright notice, 30 | * this list of conditions and the following disclaimer in the documentation 31 | * and/or other materials provided with the distribution. 32 | * 33 | * 3. Neither the name of the copyright holder nor the names of its contributors 34 | * may be used to endorse or promote products derived from this software without 35 | * specific prior written permission. 36 | * 37 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | * POSSIBILITY OF SUCH DAMAGE. 48 | ******************************************************************************** 49 | ******************************************************************************* 50 | * NOTES 51 | * 52 | * 53 | *******************************************************************************/ 54 | #include 55 | #include // cerr 56 | 57 | #include 58 | 59 | //exported functionality 60 | namespace ctl{ 61 | namespace parallel{ 62 | class Timer { 63 | typedef tbb::tick_count Clock; 64 | typedef typename tbb::tick_count time_point; 65 | public: 66 | Timer() : start_(), stop_(){} 67 | 68 | // method: start 69 | // starts timer 70 | void start() { start_ = stop_ = Clock::now(); } 71 | // method: stop 72 | void stop() { stop_ = Clock::now(); } 73 | 74 | template< typename T = std::chrono::seconds> 75 | double elapsed() const { return (stop_ - start_).seconds(); } 76 | private: 77 | time_point start_; 78 | time_point stop_; 79 | }; // class Timer 80 | } //namespace parallel 81 | } //namespace ctl 82 | 83 | #endif //CTLIB_TBB_TIMER_H 84 | -------------------------------------------------------------------------------- /ctl/persistence/compute_betti.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_WRITE_BETTI_H 2 | #define CTL_WRITE_BETTI_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | 9 | 10 | namespace ctl{ 11 | template< typename Betti, typename Out> 12 | void write_betti( const Betti & b, Out & out){ 13 | for( auto n : b) { out << n << " "; } 14 | out << std::endl; 15 | } 16 | template< typename Betti, 17 | typename Complex, 18 | typename Cell_chain_map> 19 | void compute_betti( const Complex & complex, 20 | Cell_chain_map & cascade_boundary_map, 21 | Betti & _betti){ 22 | typedef typename Complex::iterator Cell_iterator; 23 | typedef typename Cell_chain_map::value_type Chain; 24 | Betti betti( complex.dimension()+1,0); 25 | auto fm = cascade_boundary_map.index(); 26 | for(Cell_iterator cell = complex.begin(); cell != complex.end(); ++cell){ 27 | const Chain& bd = cascade_boundary_map[ cell]; 28 | const bool c = bd.empty() || 29 | (cell->first < bd.youngest().cell()->first); 30 | betti[ cell->first.dimension()-(!c)] += (2*c -1); 31 | } 32 | _betti.swap( betti); 33 | } 34 | 35 | template< typename Betti, 36 | typename Filtration, 37 | typename Cell_chain_map> 38 | void compute_betti( Filtration & filtration, 39 | Cell_chain_map & cascade_boundary_map, 40 | Betti & _betti, bool){ 41 | typedef typename Filtration::Complex Complex; 42 | typedef typename Cell_chain_map::value_type Chain; 43 | const Complex & complex = filtration.complex(); 44 | Betti betti( complex.dimension()+1,0); 45 | auto fm = cascade_boundary_map.index(); 46 | for( auto cell = filtration.begin(); 47 | cell != filtration.end(); ++cell){ 48 | const Chain& bd = cascade_boundary_map[ cell]; 49 | const bool c = bd.empty() || (cell < filtration.begin()+fm[bd.youngest().cell()]); 50 | betti[ (*cell)->first.dimension()-(!c)] += (2*c -1); 51 | } 52 | _betti.swap( betti); 53 | } 54 | 55 | 56 | 57 | }//namespace ctl 58 | #endif //CTL_WRITE_BETTI 59 | -------------------------------------------------------------------------------- /ctl/persistence/persistence_data.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_PERSISTENCE_DATA_H 2 | #define CTLIB_PERSISTENCE_DATA_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | 9 | #include 10 | 11 | namespace ctl { 12 | namespace detail{ 13 | template< typename Term_less_, 14 | typename Boundary_operator_, 15 | typename Cell_chain_map_, 16 | typename Output_policy_ > 17 | //hold onto persistence data 18 | struct Persistence_data { 19 | 20 | typedef Term_less_ Term_less; 21 | typedef Boundary_operator_ Boundary_operator; 22 | typedef Cell_chain_map_ Cell_chain_map; 23 | typedef Output_policy_ Output_policy; 24 | typedef typename boost::property_traits< Cell_chain_map>::value_type 25 | Chain; 26 | typedef typename Chain::value_type Term; 27 | 28 | Persistence_data( Term_less t, 29 | Boundary_operator & bd_, 30 | Cell_chain_map & bd_map_, 31 | Cell_chain_map & map_, 32 | Output_policy p): 33 | term_less( t), bd( bd_), cascade_boundary_map( bd_map_), 34 | cascade_map( map_), policy( p), 35 | cascade(), cascade_boundary(), temporary_chain() {}; 36 | 37 | Term_less term_less; 38 | Boundary_operator bd; 39 | Cell_chain_map& cascade_boundary_map; 40 | Cell_chain_map& cascade_map; 41 | Output_policy policy; 42 | 43 | //at each iteration we use these temporaries and then 44 | //we swap them into place in the vector. 45 | Chain cascade; 46 | Chain cascade_boundary; 47 | //when we do the x <- x+y in persistence we 48 | //end up creating a temporary: 49 | // z <- x+y 50 | // x.swap( z) 51 | // by storing this temporary here, we avoid the reallocation 52 | // at every iteration 53 | Chain temporary_chain; 54 | }; //struct Persistence_data 55 | 56 | } //end namespace detail 57 | } //end namespace ctl 58 | 59 | #endif //CTLIB_PERSISTENCE_DATA_H 60 | -------------------------------------------------------------------------------- /ctl/persistence/unpair_cells.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_UNPAIR_CELLS_H 2 | #define CTLIB_UNPAIR_CELLS_H 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2014 21 | ******************************************************************************* 22 | * NOTES 23 | * 24 | * 25 | *******************************************************************************/ 26 | 27 | #include 28 | 29 | //exported functionality 30 | namespace ctl{ 31 | template< typename Iterator, typename Cell_to_chain_map, typename Filtration_map=ctl::identity> 32 | void unpair_cells( Iterator begin, Iterator end, 33 | Cell_to_chain_map& boundary_matrix, 34 | Filtration_map fm = Filtration_map()){ 35 | for( auto i = begin; i != end; ++i){ 36 | auto & c = boundary_matrix[ i]; 37 | if ( (c.size() == 1) && (fm[ i] < c.youngest().cell())){ 38 | c.clear(); 39 | } 40 | } 41 | } 42 | } //namespace ctl 43 | 44 | 45 | #endif //CTLIB_EXAMPLE_H 46 | -------------------------------------------------------------------------------- /ctl/points/points.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_POINTS_H 2 | #define CTLIB_POINTS_H 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2014 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * 26 | * 1. Redistributions of source code must retain the above copyright notice, 27 | * this list of conditions and the following disclaimer. 28 | * 29 | * 2. Redistributions in binary form must reproduce the above copyright notice, 30 | * this list of conditions and the following disclaimer in the documentation 31 | * and/or other materials provided with the distribution. 32 | * 33 | * 3. Neither the name of the copyright holder nor the names of its contributors 34 | * may be used to endorse or promote products derived from this software without 35 | * specific prior written permission. 36 | * 37 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | * POSSIBILITY OF SUCH DAMAGE. 48 | ******************************************************************************** 49 | *******************************************************************************/ 50 | #include 51 | //exported functionality 52 | namespace ctl{ 53 | 54 | using Point = std::vector< double>; 55 | using Points = std::vector< Point>; 56 | 57 | } //namespace ctl 58 | 59 | #endif //CTLIB_POINTS_H 60 | -------------------------------------------------------------------------------- /ctl/product_cell/iterator_product_cell.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ITERATOR_PRODUCT_CELL_H 2 | #define ITERATOR_PRODUCT_CELL_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | ******************************************************************************/ 8 | /* NOTES: 9 | * This product cell design is a pair< Cell1, Cell2> 10 | * For space concerns, we represent Cell1 and Cell2 as _iterators_ 11 | * - Of course, stylistically, it would be good for Iterator_product_cell, to allow for Cell1/Cell2 to truly be 12 | the value type of these iterators 13 | */ 14 | #include //std::pair, and piecewise_construct 15 | #include //std::pair, and piecewise_construct 16 | #include //cout (debug only) 17 | #include 18 | #include 19 | 20 | namespace ctl { 21 | 22 | template< typename Cell_iterator1_, typename Cell_iterator2_> 23 | class Iterator_product_cell : public std::pair< Cell_iterator1_ , Cell_iterator2_> { 24 | public: 25 | typedef Cell_iterator1_ Cell_iterator1; 26 | typedef Cell_iterator2_ Cell_iterator2; 27 | typedef typename Cell_iterator1::value_type::first_type Cell1; 28 | typedef typename Cell_iterator2::value_type::first_type Cell2; 29 | private: 30 | typedef std::pair< Cell_iterator1_, Cell_iterator2_> Pair; 31 | typedef Iterator_product_cell< Cell_iterator1, Cell_iterator2> Self; 32 | public: 33 | 34 | //default 35 | Iterator_product_cell() {}; 36 | 37 | //copy 38 | Iterator_product_cell( const Iterator_product_cell & from) : Pair( from) {} 39 | 40 | //standard 41 | Iterator_product_cell( const Cell_iterator1 & cell1, 42 | const Cell_iterator2 & cell2): Pair( cell1, cell2) {} 43 | //initialize 44 | Iterator_product_cell( Cell_iterator1 && cell1, 45 | Cell_iterator2 && cell2): 46 | Pair( std::forward(cell1), std::forward(cell2)) {} 47 | //move 48 | Iterator_product_cell( Iterator_product_cell && from): Pair( std::forward< Pair>( from)){} 49 | 50 | //piecewise 51 | template< class... Args1, class... Args2> 52 | Iterator_product_cell( std::piecewise_construct_t pwc, 53 | std::tuple< Args1...> first_args, 54 | std::tuple second_args): 55 | Pair( pwc, first_args, second_args) {} 56 | 57 | const Cell1& first_cell() const { return this->first->first; } 58 | const Cell2& second_cell() const { return this->second->first; } 59 | std::size_t dimension() const { return first_cell().dimension() + 60 | second_cell().dimension(); } 61 | 62 | //Assignment 63 | Self& operator=( const Self & b) { 64 | Pair::operator=( b); 65 | return *this; 66 | } 67 | 68 | //Move assignment 69 | Self& operator=( Self && b) { 70 | Pair::operator=( std::forward( b)); 71 | return *this; 72 | } 73 | 74 | //Comparisons. 75 | bool operator<( const Self & b) const { 76 | if (this->first == b.first) { 77 | return second_cell() < b.second_cell(); 78 | } 79 | return first_cell() < b.first_cell(); 80 | } 81 | 82 | bool operator==( const Self & b) const { 83 | return (this->first == b.first) && (this->second == b.second); 84 | } 85 | bool operator!=( const Self & b) const { 86 | return (this->first != b.first) || (this->second != b.second); 87 | } 88 | 89 | std::size_t hash() const{ 90 | constexpr std::size_t shift_factor = sizeof(std::size_t) >> 2; 91 | return ctl::hash_function( this->first->first) | 92 | (ctl::hash_function( this->second->first) << shift_factor); 93 | } 94 | struct Hash { 95 | std::size_t operator()( const Iterator_product_cell & p) const { 96 | return p.hash(); 97 | } 98 | }; 99 | //File I/O 100 | template< typename Stream> 101 | void write( Stream & out) const { 102 | first_cell().write( out); 103 | out << ctl::otimes; 104 | second_cell().write( out); 105 | } 106 | 107 | }; //Iterator_product_cell 108 | 109 | template< typename Stream, typename T1, typename T2> 110 | Stream& operator<<(Stream& out, const Iterator_product_cell< T1, T2> && alpha){ 111 | out << alpha.first_cell() << ctl::otimes 112 | << alpha.second_cell(); 113 | return out; 114 | } 115 | template< typename Stream, typename T1, typename T2> 116 | Stream& operator<<(Stream& out, const Iterator_product_cell< T1, T2> & alpha){ 117 | out << alpha.first_cell() << ctl::otimes 118 | << alpha.second_cell(); 119 | return out; 120 | } 121 | 122 | } // namespace ctl 123 | 124 | #endif //ITERATOR_PRODUCT_CELL_H 125 | -------------------------------------------------------------------------------- /ctl/product_cell/product_cell.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PRODUCT_CELL_H 2 | #define PRODUCT_CELL_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | ******************************************************************************/ 8 | /* NOTES: 9 | * This product cell design is a pair< Cell1, Cell2> 10 | * This product_cell stores explicit factor cells, if space is a concern, consider Iterator_product_cell< Cell1, Cell2> 11 | */ 12 | #include //std::pair, and piecewise_construct 13 | #include //std::pair, and piecewise_construct 14 | #include //cout (debug only) 15 | #include 16 | #include 17 | #include 18 | 19 | namespace ctl { 20 | 21 | template< typename Cell1_, typename Cell2_> 22 | class Product_cell : public std::pair< Cell1_ , Cell2_> { 23 | public: 24 | typedef Cell1_ Cell1; 25 | typedef Cell2_ Cell2; 26 | private: 27 | typedef std::pair< Cell1, Cell2> Pair; 28 | typedef Product_cell< Cell1, Cell2> Self; 29 | public: 30 | 31 | //default 32 | Product_cell() : Pair() {}; 33 | 34 | //copy 35 | Product_cell( const Product_cell & from) : Pair( from) { } 36 | 37 | //standard 38 | Product_cell( const Cell1 & cell1, 39 | const Cell2 & cell2): Pair( cell1, cell2) {} 40 | //initialize 41 | Product_cell( Cell1 && cell1, Cell2 && cell2): Pair( std::forward(cell1), std::forward(cell2)) {} 42 | //move 43 | Product_cell( Product_cell && from): Pair( std::forward< Pair>( from)){} 44 | 45 | //piecewise 46 | template< class... Args1, class... Args2> 47 | Product_cell( std::piecewise_construct_t pwc, 48 | std::tuple< Args1...> first_args, 49 | std::tuple second_args): 50 | Pair( pwc, first_args, second_args) {} 51 | 52 | const Cell1& first_cell() const { return this->first; } 53 | const Cell2& second_cell() const { return this->second; } 54 | std::size_t dimension() const { return first_cell().dimension() + second_cell().dimension(); } 55 | 56 | //Assignment 57 | Self& operator=( const Self & b) { 58 | Pair::operator=( b); 59 | return *this; 60 | } 61 | 62 | //Move assignment 63 | Self& operator=( Self && b) { 64 | Pair::operator=( std::forward( b)); 65 | return *this; 66 | } 67 | 68 | //Comparisons. 69 | bool operator<( const Self & b) const { 70 | if (this->first == b.first) { 71 | return second_cell() < b.second_cell(); 72 | } 73 | return first_cell() < b.first_cell(); 74 | } 75 | 76 | bool operator==( const Self & b) const { return (this->first == b.first) && (this->second == b.second); } 77 | bool operator!=( const Self & b) const { return (this->first != b.first) || (this->second != b.second); } 78 | 79 | std::size_t hash() const{ 80 | constexpr std::size_t shift_factor = sizeof(std::size_t) >> 2; 81 | return ctl::hash_function( first_cell()) | 82 | (ctl::hash_function( second_cell()) << shift_factor); 83 | } 84 | 85 | struct Hash { 86 | std::size_t operator()( const Product_cell & p) const { 87 | return p.hash(); 88 | } 89 | }; 90 | //File I/O 91 | template< typename Stream> 92 | void write( Stream & out) const { 93 | first_cell().write( out); 94 | out << ctl::otimes; 95 | second_cell().write( out); 96 | } 97 | 98 | }; //Product_cell 99 | 100 | template< typename T1, typename T2> 101 | std::ostream& operator<<(std::ostream& out, const Product_cell< T1, T2> && alpha){ 102 | out << alpha.first_cell() << ctl::otimes 103 | << alpha.second_cell(); 104 | return out; 105 | } 106 | template< typename T1, typename T2> 107 | std::ostream& operator<<(std::ostream& out, const Product_cell< T1, T2> & alpha){ 108 | out << alpha.first_cell() << ctl::otimes 109 | << alpha.second_cell(); 110 | return out; 111 | } 112 | 113 | } // namespace ctl 114 | 115 | #endif //PRODUCT_CELL_H 116 | -------------------------------------------------------------------------------- /ctl/product_cell/product_cell_less.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CTL_PRODUCT_CELL_LESS_H_ 2 | #define _CTL_PRODUCT_CELL_LESS_H_ 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2011 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * 26 | * 1. Redistributions of source code must retain the above copyright notice, 27 | * this list of conditions and the following disclaimer. 28 | * 29 | * 2. Redistributions in binary form must reproduce the above copyright notice, 30 | * this list of conditions and the following disclaimer in the documentation 31 | * and/or other materials provided with the distribution. 32 | * 33 | * 3. Neither the name of the copyright holder nor the names of its contributors 34 | * may be used to endorse or promote products derived from this software without 35 | * specific prior written permission. 36 | * 37 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | * POSSIBILITY OF SUCH DAMAGE. 48 | ******************************************************************************** 49 | ******************************************************************************* 50 | * NOTES 51 | * 52 | * 53 | *******************************************************************************/ 54 | namespace ctl { 55 | // For testing 56 | // Id comparison and cover_cell ordering 57 | template< typename Cell_iterator> 58 | struct Product_first_less { 59 | typedef Cell_iterator first_argument_type; 60 | typedef Cell_iterator second_argument_type; 61 | typedef bool result_type; 62 | bool operator()( const Cell_iterator& c1, 63 | const Cell_iterator& c2) const { 64 | const auto& c1_first = c1->first.first_cell(); 65 | const auto& c1_second = c1->first.second_cell(); 66 | 67 | const auto& c2_first = c2->first.first_cell(); 68 | const auto& c2_second = c2->first.second_cell(); 69 | return (c1_first < c2_first) || ((c2_first == c1_first) && (c1_second < c2_second)); 70 | } 71 | }; // class Product_first_less 72 | 73 | template< typename Cell_iterator> 74 | struct Product_second_less { 75 | typedef Cell_iterator first_argument_type; 76 | typedef Cell_iterator second_argument_type; 77 | typedef bool result_type; 78 | private: 79 | public: 80 | bool operator()( const Cell_iterator& c1, 81 | const Cell_iterator& c2) const { 82 | 83 | const auto& c1_first = (c1)->first.first_cell(); 84 | const auto& c1_second = (c1)->first.second_cell(); 85 | 86 | const auto& c2_first = (c2)->first.first_cell(); 87 | const auto& c2_second = (c2)->first.second_cell(); 88 | return (c1_second < c2_second) || ((c2_second == c1_second) && (c1_first < c2_first)); 89 | } 90 | 91 | }; // class Product_second_less 92 | } //end namespace ctl 93 | #endif //product_cell_less 94 | -------------------------------------------------------------------------------- /ctl/term/term_less.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_TERM_LESS_H 2 | #define CTLIB_TERM_LESS_H 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2014 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * 26 | * 1. Redistributions of source code must retain the above copyright notice, 27 | * this list of conditions and the following disclaimer. 28 | * 29 | * 2. Redistributions in binary form must reproduce the above copyright notice, 30 | * this list of conditions and the following disclaimer in the documentation 31 | * and/or other materials provided with the distribution. 32 | * 33 | * 3. Neither the name of the copyright holder nor the names of its contributors 34 | * may be used to endorse or promote products derived from this software without 35 | * specific prior written permission. 36 | * 37 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | * POSSIBILITY OF SUCH DAMAGE. 48 | ******************************************************************************** 49 | *******************************************************************************/ 50 | 51 | //exported functionality 52 | namespace ctl{ 53 | 54 | template< typename Cell_less_> 55 | struct Term_cell_less{ 56 | typedef Cell_less_ Cell_less; 57 | Term_cell_less(){} 58 | Term_cell_less( const Cell_less & l): less( l){} 59 | template< typename Term> 60 | inline bool operator()( const Term & l, const Term & r) const { 61 | return less( l.cell(), r.cell()); 62 | } 63 | Cell_less less; 64 | }; //struct Term_less 65 | 66 | template< typename Cell_less_> 67 | struct Filtration_term_cell_less{ 68 | typedef Cell_less_ Cell_less; 69 | Filtration_term_cell_less(){} 70 | Filtration_term_cell_less( const Cell_less & l): less( l){} 71 | template< typename Term> 72 | inline bool operator()( const Term & l, const Term & r) const { 73 | return less( *(l.cell()), *(r.cell())); 74 | } 75 | Cell_less less; 76 | }; //struct Term_less 77 | 78 | 79 | } //namespace ctl 80 | 81 | #endif //CTLIB_TERM_LESS_H 82 | -------------------------------------------------------------------------------- /ctl/term/term_tags.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_TERM_TAGS_H 2 | #define CTLIB_TERM_TAGS_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | *******************************************************************************/ 8 | 9 | 10 | namespace ctl{ 11 | namespace detail{ 12 | struct term_z2_tag{}; 13 | struct term_non_z2_tag{}; 14 | } //detail namespace 15 | } //namespace ctl 16 | #endif //CTLIB_TERM_TAGS_H 17 | -------------------------------------------------------------------------------- /ctl/utility/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_TIMER_H 2 | #define CTLIB_TIMER_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | ******************************************************************************* 6 | * ********** BSD-3 License **************** 7 | ******************************************************************************* 8 | * NOTES 9 | * 10 | * 11 | *******************************************************************************/ 12 | #include // cerr 13 | #include 14 | 15 | #ifdef _OPENMP 16 | #include 17 | #endif 18 | 19 | //exported functionality 20 | namespace ctl{ 21 | 22 | class Timer { 23 | typedef std::chrono::steady_clock Clock; 24 | typedef typename Clock::time_point time_point; 25 | public: 26 | Timer() : start_(), stop_(){} 27 | 28 | // method: start 29 | // starts timer 30 | void start() { start_ = stop_ = Clock::now(); } 31 | 32 | // method: stop 33 | // returns time since start() in units of T, which defaults to seconds. 34 | template< typename T = std::chrono::seconds> 35 | double elapsed() const { 36 | typedef std::chrono::duration< double, typename T::period> D; 37 | return (std::chrono::duration_cast< D>(Clock::now() - start_).count()); 38 | } 39 | private: 40 | time_point start_; 41 | time_point stop_; 42 | }; // class Timer 43 | 44 | } //namespace ctl 45 | 46 | #endif //CTLIB_TIMER_H 47 | -------------------------------------------------------------------------------- /ctl/vr/incremental_complex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_INCREMENTAL_H 2 | #define CTL_INCREMENTAL_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | * ********** BSD-3 License **************** 6 | ******************************************************************************* 7 | * NOTES 8 | * This is the construction of the Vietoris Rips Complex using the all pairs 9 | * approach in the geometric phase and the incremental algorithm in the 10 | * topological phase. 11 | *******************************************************************************/ 12 | 13 | //STL 14 | #include 15 | #include 16 | 17 | //BOOST 18 | #include 19 | 20 | namespace ctl { 21 | 22 | // Given a node, we loop through all its neighbors and return a vector 23 | // of all the neighbors that have a lower ordering. 24 | template 25 | void get_lower_neighbors (const Graph& g, 26 | const Vertex& v, 27 | Points& lower_neighbors) { 28 | typedef typename boost::graph_traits::adjacency_iterator Iterator; 29 | Iterator ai, ai_end; 30 | for( boost::tie(ai, ai_end) = boost::adjacent_vertices(v, g); 31 | ai != ai_end; ++ai) { 32 | if (*ai < v) { lower_neighbors.push_back( *ai); } 33 | } 34 | } 35 | 36 | // At every level in this recursive function, we introduce a new node to our 37 | // simplicial complex and add the cofaces that arise from this new node. 38 | template 39 | void add_cofaces (const Graph& graph, Simplex& tau, 40 | const Neighbors& neighbors, 41 | Complex& complex, const std::size_t dimension) { 42 | typedef typename Neighbors::const_iterator Neighbor_iterator; 43 | complex.insert_open_cell(tau); 44 | if(tau.dimension() >= dimension) { return; } 45 | Neighbors lower_neighbors; 46 | Neighbors final_neighbors; 47 | for(Neighbor_iterator i = neighbors.begin(); i != neighbors.end(); ++i){ 48 | lower_neighbors.clear(); 49 | Simplex sigma( tau); 50 | sigma.insert( *i); 51 | get_lower_neighbors(graph, *i, lower_neighbors); 52 | final_neighbors.clear(); 53 | set_intersection(lower_neighbors.begin(),lower_neighbors.end(), 54 | neighbors.begin(),neighbors.end(), 55 | back_inserter(final_neighbors)); 56 | add_cofaces(graph, sigma, final_neighbors, complex, dimension); 57 | } 58 | } 59 | 60 | // We loop through all nodes, selecting each one as the starting point for 61 | // constructing our simplicial complex. 62 | template 63 | void incremental_vr (const Graph& g, Complex& complex, std::size_t dimension) { 64 | typedef typename Complex::Cell Simplex; 65 | typedef typename Simplex::value_type Vertex; 66 | typedef typename boost::graph_traits< Graph>::vertex_iterator vertex_iterator; 67 | vertex_iterator vi, vlast; 68 | for ( std::tie( vi, vlast) = boost::vertices( g); vi != vlast; ++vi) { 69 | std::vector< Vertex> neighbors; 70 | get_lower_neighbors(g, *vi, neighbors); 71 | Simplex tau(1, *vi); 72 | add_cofaces( g, tau, neighbors, complex, dimension); 73 | } 74 | } 75 | 76 | } //end namespace CTL 77 | #endif // CTL_INCREMENTAL_H 78 | -------------------------------------------------------------------------------- /ctl/vr/inductive_complex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTL_INDUCTIVE_H 2 | #define CTL_INDUCTIVE_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | * Copyright (C) Amr Mohamed 2014 6 | ******************************************************************************* 7 | * NOTES 8 | * This is the construction of the Vietoris Rips Complex using the all pairs 9 | * approach in the geometric phase and the inductive algorithm in the 10 | * topological phase. 11 | *******************************************************************************/ 12 | 13 | //STL 14 | #include 15 | #include 16 | #include 17 | 18 | //BOOST 19 | #include 20 | 21 | //CTL 22 | #include 23 | 24 | namespace ctl { 25 | 26 | // We add the given graph to the complex. Also, we update the cells vectors to 27 | // keep track of the dimensions of the cells. 28 | template 29 | void add_graph_to_complex (const Graph& g, 30 | Complex& complex, 31 | Vector& k_cells, 32 | Vector& k_plus_one_cells) { 33 | typedef typename Complex::Cell Simplex; 34 | typedef typename boost::graph_traits< Graph>::vertex_iterator vertex_iterator; 35 | typedef typename boost::graph_traits< Graph>::adjacency_iterator Iterator; 36 | vertex_iterator vi, vlast; 37 | for ( std::tie( vi, vlast) = boost::vertices( g); vi != vlast; ++vi) { 38 | // adding {*vi} to both k_cells and complex 39 | Simplex tau(1, *vi); 40 | k_cells.push_back(tau); 41 | complex.insert_open_cell(tau); 42 | Iterator ai, ai_end; 43 | for ( boost::tie(ai, ai_end) = boost::adjacent_vertices(*vi, g); 44 | ai != ai_end; ++ai) { 45 | // adding {*vi, *ai} to both k_plus_one_cells and complex 46 | Simplex sigma( tau); 47 | sigma.insert( *ai); 48 | k_plus_one_cells.push_back(sigma); 49 | complex.insert_open_cell(sigma); 50 | } 51 | } 52 | } 53 | 54 | // We loop through all nodes, selecting each one as the starting point for 55 | // constructing our simplicial complex. 56 | template 57 | void inductive_vr (const Graph& g, Complex& complex, std::size_t dimension) { 58 | typedef typename Complex::Cell Simplex; 59 | typedef typename Simplex::value_type Vertex; 60 | std::vector k_cells; 61 | std::vector k_plus_one_cells; 62 | // adding the graph to the complex 63 | add_graph_to_complex (g, complex, k_cells, k_plus_one_cells); 64 | // inductive algorithm 65 | std::vector< Vertex> intersect; 66 | for ( int k = 1; k < dimension; k++) { 67 | k_cells.swap(k_plus_one_cells); 68 | k_plus_one_cells.clear(); 69 | for( const auto & tau: k_cells){ 70 | // getting the intersection of all lower neighbors 71 | std::vector< Vertex> final_neighbors; 72 | std::vector< Vertex> lower_neighbors; 73 | ctl::get_lower_neighbors(g, *(tau.begin()), final_neighbors); 74 | for( auto & vi: tau) { 75 | if( final_neighbors.empty()) { break; } 76 | lower_neighbors.clear(); 77 | ctl::get_lower_neighbors( g, vi, lower_neighbors); 78 | //std::vector< Vertex> intersect; 79 | set_intersection(lower_neighbors.begin(), 80 | lower_neighbors.end(), 81 | final_neighbors.begin(), 82 | final_neighbors.end(), 83 | std::back_inserter(intersect)); 84 | final_neighbors.swap(intersect); 85 | intersect.clear(); 86 | //final_neighbors.clear(); 87 | //std::copy (intersect.begin(),intersect.end(),back_inserter(final_neighbors)); 88 | } 89 | // constructing new simplices and adding them to the complex 90 | for( int j = 0; j < final_neighbors.size(); j++) { 91 | Simplex sigma( tau); 92 | sigma.insert( final_neighbors[j]); 93 | k_plus_one_cells.push_back(sigma); 94 | complex.insert_open_cell(sigma); 95 | } 96 | } 97 | } 98 | } 99 | 100 | } //end namespace CTL 101 | #endif // CTL_INDUCTIVE_H 102 | -------------------------------------------------------------------------------- /ctl/vr/vr.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //CTL 5 | //Utility 6 | #include 7 | #include 8 | 9 | 10 | //Types for Points 11 | //#include 12 | 13 | //Types for Graphs 14 | #include 15 | 16 | //Types for Building a Simplicial Chain Complex 17 | //Abstract Simplex 18 | #include 19 | #include 20 | #include 21 | 22 | //Chain Complex 23 | #include 24 | #include 25 | #include 26 | 27 | //VR Construction 28 | #include 29 | //#include 30 | #include 31 | 32 | namespace ctl { 33 | 34 | template< typename It1, typename It2> 35 | double lp( It1 begin1, It1 end1, It2 begin2, It2 end2){ 36 | double r = 0.0; 37 | for( ; begin1 != end1; ++begin2, ++begin2){ 38 | double v = (*begin1 - *begin2); 39 | r += v*v; 40 | } 41 | return r; 42 | } 43 | 44 | template< typename Points> 45 | ctl::Cell_complex< ctl::Simplex_boundary> 46 | vr(const Points& points, double epsilon, std::size_t dimension){ 47 | //Simplex 48 | typedef typename ctl::Nbhd_graph<> Graph; 49 | 50 | //Chain Complex 51 | typedef ctl::Cell_complex< ctl::Simplex_boundary> Complex; 52 | Graph graph; 53 | Complex complex; 54 | ctl::all_pairs::construct_graph(points, epsilon, graph); 55 | //TODO: glue in other algorithms 56 | ctl::incremental_vr( graph, complex, dimension); 57 | return complex; 58 | } 59 | 60 | } //end namespace ctl 61 | -------------------------------------------------------------------------------- /ctl/weight_data/weight_data.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_WEIGHT_DATA_H 2 | #define CTLIB_WEIGHT_DATA_H 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2014 5 | *******************************************************************************/ 6 | 7 | //non-exported functionality 8 | namespace ctl { 9 | namespace detail{} // end namespace detail 10 | } //ctl namespace 11 | 12 | //exported functionality 13 | namespace ctl{ 14 | 15 | template< typename Weight_, typename Weight_less_ = std::less< Weight_> > 16 | class Weight_data { 17 | public: 18 | typedef Weight_ Weight; 19 | typedef Weight_less_ Weight_less; 20 | typedef std::numeric_limits< Weight_> limits; 21 | Weight_data(): weight_( Weight( limits::infinity())), less() {} 22 | Weight_data( const Weight& weight) : weight_( weight), less() {} 23 | Weight_data( const Weight_data &from) : weight_( from.weight_), less() {} 24 | Weight_data( Weight_data &&from) : weight_( std::move( from.weight_)), less() {} 25 | 26 | 27 | 28 | bool operator<( const Weight_data & d) const { 29 | return less( weight_, d.weight_); 30 | } 31 | // assignment operator 32 | Weight_data& operator=( const Weight_data& from) { 33 | weight_ = from.weight_; 34 | return *this; 35 | } 36 | // assignment operator 37 | Weight_data& operator=( Weight_data&& from) { 38 | weight_ = std::move( from.weight_); 39 | return *this; 40 | } 41 | void uninitialize_weight() { weight_ = limits::infinity(); } 42 | bool initialized() const { return !(weight_ == limits::infinity()); } 43 | Weight& weight() { return weight_; } 44 | void weight( const Weight & w) { weight_ = w; } 45 | const Weight weight() const { return weight_; } 46 | private: 47 | Weight_ weight_; 48 | Weight_less_ less; 49 | }; // class Weight_data 50 | 51 | } //namespace ctl 52 | 53 | 54 | #endif //CTLIB_WEIGHT_DATA_H 55 | -------------------------------------------------------------------------------- /ctl/weight_data/weight_functor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTLIB_WEIGHT_FUNCTOR_H 2 | #define CTLIB_WEIGHT_FUNCTOR_H 3 | /******************************************************************************* 4 | * -Academic Honesty- 5 | * Plagarism: The unauthorized use or close imitation of the language and 6 | * thoughts of another author and the representation of them as one's own 7 | * original work, as by not crediting the author. 8 | * (Encyclopedia Britannica, 2008.) 9 | * 10 | * You are free to use the code according to the license below, but, please 11 | * do not commit acts of academic dishonesty. We strongly encourage and request 12 | * that for any [academic] use of this source code one should cite one the 13 | * following works: 14 | * 15 | * \cite{hatcher, z-ct-10} 16 | * 17 | * See ct.bib for the corresponding bibtex entries. 18 | * !!! DO NOT CITE THE USER MANUAL !!! 19 | ******************************************************************************* 20 | * Copyright (C) Ryan H. Lewis 2014 21 | ******************************************************************************* 22 | * ********** BSD-3 License **************** 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * 26 | * 1. Redistributions of source code must retain the above copyright notice, 27 | * this list of conditions and the following disclaimer. 28 | * 29 | * 2. Redistributions in binary form must reproduce the above copyright notice, 30 | * this list of conditions and the following disclaimer in the documentation 31 | * and/or other materials provided with the distribution. 32 | * 33 | * 3. Neither the name of the copyright holder nor the names of its contributors 34 | * may be used to endorse or promote products derived from this software without 35 | * specific prior written permission. 36 | * 37 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 | * POSSIBILITY OF SUCH DAMAGE. 48 | ******************************************************************************** 49 | ******************************************************************************* 50 | * NOTES 51 | * 52 | * 53 | *******************************************************************************/ 54 | //STL 55 | #include 56 | 57 | //CTL 58 | #include 59 | #include 60 | 61 | //non-exported functionality 62 | namespace ctl { 63 | namespace detail{} // end namespace detail 64 | } //ctl namespace 65 | 66 | //exported functionality 67 | namespace ctl{ 68 | 69 | template< typename Complex> 70 | struct Weight_data_functor { 71 | typedef typename Complex::Data Weight_data; 72 | typedef typename Weight_data::Weight Weight; 73 | typedef Weight result_type; 74 | typedef typename Complex::Cell Cell; 75 | 76 | Weight_data_functor& operator=( const Weight_data_functor & f){ 77 | return *this; 78 | } 79 | 80 | Weight_data_functor& operator=( Weight_data_functor && f){ 81 | return *this; 82 | } 83 | 84 | //the output operator 85 | const Weight& operator()( const Weight_data & data) const { 86 | return data.weight(); 87 | } 88 | 89 | Weight& operator()( Weight_data & data) const { return data.weight(); } 90 | }; //end struct Weight_data_functor 91 | 92 | // Functor for comparison 93 | struct Weight_less { 94 | template< typename Iterator> 95 | bool operator()( const Iterator& c1, 96 | const Iterator& c2) const 97 | { 98 | // second to get data - problematic 99 | if( c1->second.weight() < c2->second.weight()) { return true; } 100 | if( c1->second.weight() > c2->second.weight()) { return false; } 101 | return c1->first < c2->first; 102 | } 103 | }; // class Weight_less 104 | 105 | 106 | 107 | 108 | } //namespace ctl 109 | 110 | #endif //CTLIB_WEIGHT_DATA_FUNCTOR_H 111 | -------------------------------------------------------------------------------- /dependencies/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/dependencies/CMakeModules") 2 | set(CMAKE_PREFIX_PATH /usr/lib64/openmpi) 3 | 4 | find_package(Boost COMPONENTS program_options serialization REQUIRED) 5 | find_package( MPI REQUIRED) 6 | find_package( TBB REQUIRED) 7 | find_package( METIS REQUIRED) 8 | find_package( Doxygen) 9 | find_package( ANN) 10 | 11 | include_directories(${Boost_INCLUDE_DIR}) 12 | link_directories(${Boost_LIBRARY_DIR}) 13 | 14 | include_directories( ${MPI_INCLUDE_DIR}) 15 | link_directories( ${MPI_LIBRARY_DIR}) 16 | 17 | include_directories(${TBB_INCLUDE_DIR}) 18 | link_directories(${TBB_LIBRARY_DIR}) 19 | set(TBB_LIBRARIES ${TBB_LIBRARIES} ) 20 | 21 | include_directories(${METIS_INCLUDE_DIR}) 22 | link_directories(${METIS_LIBRARY_DIR}) 23 | 24 | include_directories(${ANN_INCLUDE_DIR}) 25 | link_directories(${ANN_LIBRARY_DIR}) 26 | 27 | 28 | 29 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 30 | 31 | if(DOXYGEN_FOUND) 32 | configure_file(${CMAKE_SOURCE_DIR}/doc/Doxyfile.in 33 | ${CMAKE_BINARY_DIR}/Doxyfile @ONLY) 34 | add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile 35 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 36 | COMMENT "Generating API documentation with Doxygen" VERBATIM 37 | ) 38 | endif(DOXYGEN_FOUND) 39 | -------------------------------------------------------------------------------- /dependencies/CMakeModules/CXX11.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Nathan Osman 2 | 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | # THE SOFTWARE. 20 | 21 | # Determines whether or not the compiler supports C++11 22 | macro(check_for_cxx11_compiler _VAR) 23 | message(STATUS "Checking for C++11 compiler") 24 | set(${_VAR}) 25 | if((MSVC AND (MSVC10 OR MSVC11 OR MSVC12)) OR 26 | (CMAKE_COMPILER_IS_GNUCXX AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.6) OR 27 | (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.1)) 28 | set(${_VAR} 1) 29 | message(STATUS "Checking for C++11 compiler - available") 30 | else() 31 | message(STATUS "Checking for C++11 compiler - unavailable") 32 | endif() 33 | endmacro() 34 | 35 | # Sets the appropriate flag to enable C++11 support 36 | macro(enable_cxx11) 37 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 38 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 39 | endif() 40 | endmacro 41 | -------------------------------------------------------------------------------- /dependencies/CMakeModules/FindANN.cmake: -------------------------------------------------------------------------------- 1 | # Find the native ANN headers and libraries. 2 | # 3 | # ANN_INCLUDE_DIRS - where to find nana/nana.h, etc. 4 | # ANN_LIBRARIES - List of libraries when using nana. 5 | # ANN_FOUND - True if nana found. 6 | 7 | # Look for the header file. 8 | FIND_PATH(ANN_INCLUDE_DIR NAMES ANN/ANN.h PATHS /usr/include/ /usr/include/ANN /opt/local/include/ANN /usr/local/include/ANN $ENV{ANN_DIR}/include/) 9 | MARK_AS_ADVANCED(ANN_INCLUDE_DIR) 10 | 11 | # Look for the library. 12 | FIND_LIBRARY(ANN_LIBRARY NAMES ANN PATHS /usr/lib /opt/local/lib $ENV{ANN_DIR}/lib) 13 | if( NOT ANN_LIBRARY) 14 | FIND_LIBRARY(ANN_LIBRARY NAMES ann PATHS /usr/lib /opt/local/lib $ENV{ANN_DIR}/lib) 15 | endif() 16 | set(ANN_LIBRARIES ${ANN_LIBRARY}) 17 | MARK_AS_ADVANCED(ANN_LIBRARY ANN_LIBRARIES ANN_LIBRARY_DIR) 18 | 19 | # handle the QUIETLY and REQUIRED arguments and set ANN_FOUND to TRUE if 20 | # all listed variables are TRUE 21 | INCLUDE(FindPackageHandleStandardArgs) 22 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(ANN DEFAULT_MSG ANN_LIBRARY ANN_INCLUDE_DIR) 23 | 24 | IF(ANN_FOUND) 25 | SET(ANN_LIBRARIES ${ANN_LIBRARY}) 26 | SET(ANN_INCLUDE_DIRS ${ANN_INCLUDE_DIR}) 27 | ELSE(ANN_FOUND) 28 | SET(ANN_LIBRARIES) 29 | SET(ANN_INCLUDE_DIRS) 30 | ENDIF(ANN_FOUND) 31 | -------------------------------------------------------------------------------- /doc/AUTHORS: -------------------------------------------------------------------------------- 1 | This BSD library is written and maintained by the authors below: 2 | 3 | Ryan H. Lewis 4 | Amr. M. Mohamed 5 | 6 | Packagers: 7 | Ubuntu: Gard Spreeman 8 | Fedora: Ryan H. Lewis 9 | OSX: Ryan H. Lewis 10 | -------------------------------------------------------------------------------- /doc/Doxyfile.in: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = ctl 2 | PROJECT_NUMBER = 0.1 3 | HIDE_UNDOC_MEMBERS = NO 4 | HIDE_UNDOC_CLASSES = NO 5 | SOURCE_BROWSER = YES 6 | @INCLUDE_PATH = @PROJECT_SOURCE_DIR@/ctl 7 | INPUT = @PROJECT_SOURCE_DIR@/ctl 8 | OUTPUT_DIRECTORY=@CMAKE_BINARY_DIR@/doc/doxygen 9 | FILE_PATTERNS = *.cpp *.hpp 10 | EXCLUDE_SYMBOLS = ctl::detail::* detail::* std::* 11 | GENERATE_XML = YES 12 | RECURSIVE = YES 13 | EXCLUDE_PATTERNS = *.asc *.cov *.nrv 14 | ALPHABETICAL_INDEX = YES 15 | COLS_IN_ALPHA_INDEX = 3 16 | IGNORE_PREFIX = Q 17 | ENABLE_PREPROCESSING = YES 18 | MACRO_EXPANSION = YES 19 | -------------------------------------------------------------------------------- /doc/LICENSE: -------------------------------------------------------------------------------- 1 | * ********** BSD-3 License **************** 2 | * Redistribution and use in source and binary forms, with or without 3 | * modification, are permitted provided that the following conditions are met: 4 | * 5 | * 1. Redistributions of source code must retain the above copyright notice, 6 | * this list of conditions and the following disclaimer. 7 | * 8 | * 2. Redistributions in binary form must reproduce the above copyright notice, 9 | * this list of conditions and the following disclaimer in the documentation 10 | * and/or other materials provided with the distribution. 11 | * 12 | * 3. Neither the name of the copyright holder nor the names of its contributors 13 | * may be used to endorse or promote products derived from this software without 14 | * specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | ******************************************************************************** 28 | -------------------------------------------------------------------------------- /man/build_clique.1: -------------------------------------------------------------------------------- 1 | .TH BUILD_CLIQUE 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B build_clique 4 | \- To build a full simplicial complex on a clique graph 5 | .SH SYNOPSIS 6 | build_clique filename num_vertices 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | builds a complex with O(2^n) vertices called filename.asc 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/complex_size.1: -------------------------------------------------------------------------------- 1 | .TH COMPLEX_SIZE 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B complex_size 4 | \- writes out a number of important features for the space 5 | .SH SYNOPSIS 6 | complex_size [options] input_file 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | prints the number of cells and other statistics on the complex 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/concurrent_homology.1: -------------------------------------------------------------------------------- 1 | .TH CONCURRENT_HOMOLOGY 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B concurrent_homology 4 | \- computes the homology of a space in parallel 5 | .SH SYNOPSIS 6 | concurrent_homology input-file num-parts: 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Uses a graph partitioning algorithm to find a partition of the underlying graph with num-parts 11 | pieces, then it bootraps this to a (num-parts+1) size cover of the input complex. It computes 12 | the homology of this space in parallel 13 | .br 14 | .SH VERSION 15 | This documentation describes 16 | .B build_clique 17 | version 0.1 18 | .SH "SEE ALSO" 19 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 20 | .br 21 | .I http://ctl.appliedtopology.org site 22 | .SH AUTHOR 23 | .br 24 | .B Ryan H. Lewis 25 | .br 26 | .I \ 27 | -------------------------------------------------------------------------------- /man/cover_homology.1: -------------------------------------------------------------------------------- 1 | .TH COVER_HOMOLOGY 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B cover_homology 4 | \- computes the homology of a space in parallel 5 | .SH SYNOPSIS 6 | cover_homology input-file num-parts: 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Uses a graph partitioning algorithm to find a partition of the underlying graph with num-parts 11 | pieces, then it bootraps this to a (num-parts) size open cover of the input complex. It computes 12 | the homology of this space in parallel. Uses less memory and may be faster than concurrent_homology. 13 | .br 14 | .SH VERSION 15 | This documentation describes 16 | .B build_clique 17 | version 0.1 18 | .SH "SEE ALSO" 19 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 20 | .br 21 | .I http://ctl.appliedtopology.org site 22 | .SH AUTHOR 23 | .br 24 | .B Ryan H. Lewis 25 | .br 26 | .I \ 27 | -------------------------------------------------------------------------------- /man/duplicate.1: -------------------------------------------------------------------------------- 1 | .TH DUPLICATE 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B duplicate 4 | \- creates the disjoint union of a space with itself N times. 5 | .SH SYNOPSIS 6 | duplicate input_name num_duplicates (=2) 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | This algorithm just creates a number of copies of the input space and writes it to 11 | a file called input_name.num_duplicates.asc 12 | .br 13 | .SH VERSION 14 | This documentation describes 15 | .B build_clique 16 | version 0.1 17 | .SH "SEE ALSO" 18 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 19 | .br 20 | .I http://ctl.appliedtopology.org site 21 | .SH AUTHOR 22 | .br 23 | .B Ryan H. Lewis 24 | .br 25 | .I \ 26 | -------------------------------------------------------------------------------- /man/euler.1: -------------------------------------------------------------------------------- 1 | .TH EULER 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B euler 4 | \- writes out the euler characteristic for the space 5 | .SH SYNOPSIS 6 | complex_size [options] input_file 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | writes out the euler characteristic for the space 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/gpcover.1: -------------------------------------------------------------------------------- 1 | .TH GPCOVER 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B gpcover 4 | \- computes a graph partition cover of a space in parallel 5 | .SH SYNOPSIS 6 | concurrent_homology input-file num-parts: 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Uses a graph partitioning algorithm to find a partition of the underlying graph with num-parts 11 | pieces, then it bootraps this to a (num-parts+1) size cover of the input complex. 12 | .br 13 | .SH VERSION 14 | This documentation describes 15 | .B build_clique 16 | version 0.1 17 | .SH "SEE ALSO" 18 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 19 | .br 20 | .I http://ctl.appliedtopology.org site 21 | .SH AUTHOR 22 | .br 23 | .B Ryan H. Lewis 24 | .br 25 | .I \ 26 | -------------------------------------------------------------------------------- /man/metowgh.1: -------------------------------------------------------------------------------- 1 | .TH METOWGHT 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B metowgh 4 | \- Converts a metis graph file to a weighted graph file 5 | .SH SYNOPSIS 6 | metowgh graph 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Writes out a weighted graph file given a metis graph file 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/oneskeleton.1: -------------------------------------------------------------------------------- 1 | .TH ONESKELETON 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B oneskeleton 4 | \- extracts the underlying graph from the space 5 | .SH SYNOPSIS 6 | one_skeleton [options] input_file 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Extracts the underlying graph from the complex 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/persistence.1: -------------------------------------------------------------------------------- 1 | .TH PERSISTENCE 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B persistence 4 | \- Computes the persistence homology of a space with a filtration 5 | .SH SYNOPSIS 6 | persistence complex_name.asc 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Presently limited, it assumes a filtration on the input complex. later it will take a filtration file as input. does not yet write the barcodes out. coming soon. 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B persistence 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, euler, complex_size, cover_homology, write_filtration, wghtomet, metowgh, gpcover, oneskeleton, concurrent_homology 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/wghtomet.1: -------------------------------------------------------------------------------- 1 | .TH WGHTOMET 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B wghtomet 4 | \- Converts a weighted graph file to a metis graph file 5 | .SH SYNOPSIS 6 | wghtomet graph 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | writes out a metis file for an input graph 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /man/write_filtration.1: -------------------------------------------------------------------------------- 1 | .TH WRITE_FILTRATION 1 "v\ 0.1" "Sun, April 27, 2014" "DARWIN\ \-\ MAC\ OS\ X" 2 | .SH NAME 3 | .B write_filtration 4 | \- writes a filtration for the given input file 5 | .SH SYNOPSIS 6 | write_filtration [options] input_file 7 | .br 8 | .SH OPTIONS 9 | .SH DESCRIPTION 10 | Extracts a filtration for the complex 11 | .br 12 | .SH VERSION 13 | This documentation describes 14 | .B build_clique 15 | version 0.1 16 | .SH "SEE ALSO" 17 | build_clique, concurrent_homology, duplicate, gpcover, oneskeleton, wghtomet, complex_size, cover_homology, euler, metowgh, persistence, write_filtration 18 | .br 19 | .I http://ctl.appliedtopology.org site 20 | .SH AUTHOR 21 | .br 22 | .B Ryan H. Lewis 23 | .br 24 | .I \ 25 | -------------------------------------------------------------------------------- /python/ctl.cpp: -------------------------------------------------------------------------------- 1 | //Required header for using pybind11 2 | #include 3 | 4 | //Automatic conversions of stl containers to Python ones 5 | #include 6 | 7 | //Additional support for operators and numpy 8 | #include 9 | #include 10 | #include 11 | 12 | //All the things we're going to wrap 13 | #include 14 | 15 | namespace py = pybind11; 16 | 17 | template< typename T> 18 | std::function 19 | stream_to_string(){ 20 | return [](const T& t){ 21 | std::stringstream ss; 22 | ss << t; 23 | return ss.str(); 24 | }; 25 | } 26 | 27 | #include "wrap_ff.hpp" 28 | #include "wrap_term.hpp" 29 | #include "wrap_simplex.hpp" 30 | //#include "wrap_cube.hpp" 31 | #include "wrap_complex.hpp" 32 | #include "wrap_persistence.hpp" 33 | #include "wrap_vr.hpp" 34 | #include "wrap_product.hpp" 35 | #include "wrap_prod_complex.hpp" 36 | 37 | decltype(auto) 38 | sc_open_star_cover( ctl::Simplicial_complex<>& sc, 39 | std::function< std::size_t(std::size_t)>& f){ 40 | return ctl::open_star_cover( sc, f); 41 | } 42 | 43 | decltype(auto) 44 | make_blowup_impl( ctl::Simplicial_complex<>& K, std::vector< ctl::Abstract_simplex>& sc){ 45 | typedef ctl::Prod_simplicial_complex Blowup; 46 | typedef typename Blowup::Cell Product_cell; 47 | Blowup blowup; 48 | std::size_t index = 0; 49 | //std::cout << K.size() << " " << sc.size() << std::endl; 50 | for( const auto & sigma : K){ 51 | const auto& tau = sc[index]; 52 | //std::cout << "sigma: " << sigma.first << " " << "tau: " << tau << std::endl; 53 | Product_cell pd( sigma.first, tau); 54 | blowup.insert_closed_cell( pd); 55 | index++; 56 | } 57 | return blowup; 58 | } 59 | 60 | decltype(auto) 61 | make_blowup( ctl::Simplicial_complex<>& K, std::list< ctl::Abstract_simplex>& sc){ 62 | std::vector< ctl::Abstract_simplex> wtf( std::begin(sc), std::end(sc)); 63 | return make_blowup_impl(K, wtf); 64 | } 65 | 66 | //## Define the module 67 | //This is where we actually define the `ctl` module. We'll also have a `phat` module that's written 68 | PYBIND11_PLUGIN(ctl) { 69 | //Create the module object. First arg is the name, second is the module docstring. 70 | py::module m("ctl", "C++ wrapper for CTL."); 71 | //Wrap the `persistence_pairs` class 72 | wrap_ff<2>(m); 73 | wrap_ff<3>(m); 74 | wrap_ff<5>(m); 75 | wrap_ff<7>(m); 76 | wrap_ff<11>(m); 77 | wrap_simplex(m); 78 | //wrap_cube(m); 79 | wrap_product(m); 80 | wrap_complex(m); 81 | wrap_prod_complex(m); 82 | wrap_persistence(m); 83 | wrap_vr(m); 84 | m.def("open_star_vtx_cover", &sc_open_star_cover, "produce a cover and nerve where the open star of vertex `i` in the complex is put into set f[i]"); 85 | m.def("make_blowup", &make_blowup, "produce a blowup of the input complex and corresponding nerve"); 86 | //We're done! 87 | return m.ptr(); 88 | 89 | } 90 | -------------------------------------------------------------------------------- /python/wrap_complex.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for an `Simplex_boundary`. 2 | void wrap_complex(py::module &mod){ 3 | using s = ctl::Simplicial_complex<>; 4 | typedef typename s::Cell c; 5 | py::class_(mod, std::string("Cell_data").c_str()) 6 | .def(py::init()) 7 | .def(py::init< typename s::Data>()) 8 | .def("__str__", stream_to_string< typename s::Data>()); 9 | 10 | py::class_(mod, std::string("Simplicial_complex").c_str()) 11 | //Default no-args constructor 12 | .def(py::init()) 13 | .def("__init__", 14 | [](s &instance, std::list arg) { 15 | new (&instance) s(std::begin(arg), std::end(arg)); 16 | }) 17 | .def("__init__", 18 | [](s &instance, std::vector arg) { 19 | new (&instance) s(std::begin(arg), std::end(arg)); 20 | }) 21 | .def("__init__", 22 | [](s &instance, std::set arg) { 23 | new (&instance) s(std::begin(arg), std::end(arg)); 24 | }) 25 | 26 | //.def("find_cell", &s::find_cell) 27 | .def("insert_open_cell", [](s& cmplx, const s::Cell & c){ 28 | cmplx.insert_open_cell( c); 29 | return cmplx; 30 | }, "insert simplex") 31 | .def("insert_closed_cell", [](s& cmplx, const s::Cell & c){ 32 | cmplx.insert_closed_cell( c); 33 | return cmplx; 34 | }, "insert simplex and its boundary") 35 | .def("dimension", &s::dimension, "dimension of complex") 36 | .def("size", &s::size, "number of simplices") 37 | .def("__len__", &s::size) 38 | .def("__contains__", [](const s &cmplx, const s::Cell& c){ 39 | return (cmplx.find_cell( c) != cmplx.end()); 40 | }) 41 | .def("is_closed", &s::is_closed, "check if all faces of all simplices exist") 42 | .def("__iter__", [](const s &c) { 43 | return py::make_iterator(c.begin(), c.end()); 44 | }, py::keep_alive<0, 1>()) 45 | .def("__str__", stream_to_string()) 46 | .def(py::self == py::self) 47 | .def(py::self != py::self); 48 | py::implicitly_convertible, s >(); 49 | py::implicitly_convertible, s >(); 50 | py::implicitly_convertible, s >(); 51 | } 52 | -------------------------------------------------------------------------------- /python/wrap_cube.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for a `Cube.` 2 | void wrap_cube(py::module &mod){ 3 | using s = ctl::Cube; 4 | typedef s::value_type v; 5 | py::class_(mod, std::string("Cube").c_str()) 6 | //Default no-args constructor 7 | .def(py::init()) 8 | .def("__init__", 9 | [](s &instance, std::list arg) { 10 | new (&instance) s(std::begin(arg), std::end(arg)); 11 | }) 12 | .def("__init__", 13 | [](s &instance, std::vector arg) { 14 | new (&instance) s(std::begin(arg), std::end(arg)); 15 | }) 16 | .def("__init__", 17 | [](s &instance, std::set arg) { 18 | new (&instance) s(std::begin(arg), std::end(arg)); 19 | }) 20 | //.def(py::init>()) 21 | .def("__len__", &s::size) 22 | .def("size", &s::size, "size of simplex") 23 | .def("capacity", &s::capacity, "capacity") 24 | .def("insert", [](s& cube, const v& interval){ 25 | cube.insert(interval); 26 | return cube; 27 | }, "inserts a vertex", py::arg("v")) 28 | .def("remove", [](s& cube, const v& interval){ 29 | cube.remove(interval); 30 | return cube; 31 | }, "removes a vertex", py::arg("v")) 32 | .def("reserve", &s::reserve, "reserve capacity", py::arg("n")) 33 | .def("clear", &s::clear, "clear the simplex") 34 | .def("dimension", &s::dimension, "dimension of simplex") 35 | .def("__contains__", [](const s &cube, const v& interval){ 36 | return std::binary_search(cube.begin(), cube.end(), interval); 37 | }) 38 | 39 | // Essential: keep object alive while iterator exists 40 | .def("__iter__", [](const s &cube) { return py::make_iterator(cube.begin(), cube.end());}, py::keep_alive<0, 1>()) 41 | .def(py::self == py::self) 42 | .def(py::self != py::self) 43 | .def(py::self < py::self); 44 | py::implicitly_convertible, s >(); 45 | py::implicitly_convertible, s >(); 46 | py::implicitly_convertible, s >(); 47 | } 48 | -------------------------------------------------------------------------------- /python/wrap_ff.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for an `Simplex_boundary`. 2 | template< std::size_t prime> 3 | void wrap_ff(py::module &mod){ 4 | typedef ctl::Finite_field FF; 5 | py::class_(mod, (std::string("Z")+std::to_string(prime)).c_str()) 6 | .def(py::init()) 7 | .def(py::init()) 8 | //.def(py::self++) 9 | //.def(py::self--) 10 | .def(py::self+=py::self) 11 | .def(py::self-=py::self) 12 | .def(py::self+py::self) 13 | .def(py::self-py::self) 14 | .def(py::self/py::self) 15 | .def(py::self/=py::self) 16 | .def(py::self*=py::self) 17 | .def(py::self < py::self) 18 | .def("to_integral", &FF::to_integral) 19 | .def("__str__", stream_to_string()) 20 | .def(py::self < py::self) 21 | .def(py::self > py::self) 22 | .def(py::self <= py::self) 23 | .def(py::self >= py::self) 24 | .def(py::self == py::self) 25 | .def(py::self != py::self); 26 | py::implicitly_convertible(); 27 | } 28 | -------------------------------------------------------------------------------- /python/wrap_prod_complex.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for an `Simplex_boundary`. 2 | void wrap_prod_complex(py::module &mod){ 3 | using s = ctl::Product_complex< ctl::Simplex_boundary, ctl::Simplex_boundary>; 4 | 5 | typedef typename s::Cell c; 6 | py::class_(mod, std::string("Prod_simplicial_complex").c_str()) 7 | //Default no-args constructor 8 | .def(py::init()) 9 | .def("__init__", 10 | [](s &instance, std::list arg) { 11 | new (&instance) s(std::begin(arg), std::end(arg)); 12 | }) 13 | .def("__init__", 14 | [](s &instance, std::vector arg) { 15 | new (&instance) s(std::begin(arg), std::end(arg)); 16 | }) 17 | .def("__init__", 18 | [](s &instance, std::set arg) { 19 | new (&instance) s(std::begin(arg), std::end(arg)); 20 | }) 21 | 22 | //.def("find_cell", &s::find_cell) 23 | .def("insert_open_cell", [](s& cmplx, const s::Cell & c){ 24 | cmplx.insert_open_cell( c); 25 | return cmplx; 26 | }, "insert simplex") 27 | .def("insert_closed_cell", [](s& cmplx, const s::Cell & c){ 28 | cmplx.insert_closed_cell( c); 29 | return cmplx; 30 | }, "insert simplex and its boundary") 31 | .def("dimension", &s::dimension, "dimension of complex") 32 | .def("size", &s::size, "number of simplices") 33 | .def("__len__", &s::size) 34 | .def("__contains__", [](const s &cmplx, const s::Cell& c){ 35 | return (cmplx.find_cell( c) != cmplx.end()); 36 | }) 37 | .def("is_closed", &s::is_closed, "check if all faces of all simplices exist") 38 | .def("__iter__", [](const s &c) { 39 | return py::make_iterator(c.begin(), c.end()); 40 | }, py::keep_alive<0, 1>()) 41 | .def("__str__", stream_to_string()) 42 | .def(py::self == py::self) 43 | .def(py::self != py::self); 44 | py::implicitly_convertible, s >(); 45 | py::implicitly_convertible, s >(); 46 | py::implicitly_convertible, s >(); 47 | } 48 | -------------------------------------------------------------------------------- /python/wrap_product.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for an `Abstract_simplex`. 2 | void wrap_product(py::module &mod){ 3 | using s = ctl::Product_cell< ctl::Abstract_simplex, ctl::Abstract_simplex >; 4 | py::class_(mod, std::string("Simplex_product").c_str()) 5 | //Default no-args constructor 6 | .def(py::init()) 7 | .def(py::init ()) 8 | 9 | .def("dimension", &s::dimension, "dimension") 10 | .def("__str__", stream_to_string()) 11 | .def("first_cell", [](const s& product){ 12 | return product.first_cell(); 13 | }, 14 | "first cell", py::keep_alive<0,1>()) 15 | 16 | .def("second_cell", [](const s& product){ 17 | return product.second_cell(); 18 | }, 19 | "second cell", py::keep_alive<0,1>()) 20 | .def(py::self == py::self) 21 | .def(py::self != py::self) 22 | .def(py::self < py::self); 23 | 24 | wrap_term>(mod, "Term_Product_Z2"); 25 | wrap_term>(mod, "Term_Product_Z3"); 26 | wrap_term>(mod, "Term_Product_Z5"); 27 | 28 | using b = ctl::Product_boundary< ctl::Simplex_boundary, ctl::Simplex_boundary> ; 29 | py::class_(mod, std::string("Simplex_product_boundary").c_str()) 30 | //Default no-args constructor 31 | .def(py::init()) 32 | .def("__call__", [](const b &bd, const s& smplx) { 33 | return py::make_iterator(bd.begin(smplx), bd.end(smplx), py::return_value_policy::move); 34 | }, py::keep_alive<0, 1>()) 35 | .def("length", [](const b& bd, const s& smplx){ 36 | return bd.length( smplx); 37 | }, "length of the boundary"); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /python/wrap_simplex.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for an `Abstract_simplex`. 2 | void wrap_simplex(py::module &mod){ 3 | using s = ctl::Abstract_simplex; 4 | typedef s::vertex_type v; 5 | py::class_(mod, std::string("Abstract_simplex").c_str()) 6 | //Default no-args constructor 7 | .def(py::init()) 8 | .def("__init__", 9 | [](s &instance, std::list arg) { 10 | new (&instance) s(std::begin(arg), std::end(arg)); 11 | }) 12 | .def("__init__", 13 | [](s &instance, std::vector arg) { 14 | new (&instance) s(std::begin(arg), std::end(arg)); 15 | }) 16 | .def("__init__", 17 | [](s &instance, std::set arg) { 18 | new (&instance) s(std::begin(arg), std::end(arg)); 19 | }) 20 | //.def(py::init>()) 21 | .def("__len__", &s::size) 22 | .def("size", &s::size, "size of simplex") 23 | .def("capacity", &s::capacity, "capacity") 24 | .def("insert", [](s& smplx, const v& vtx){ 25 | smplx.insert(vtx); 26 | return smplx; 27 | }, "inserts a vertex", py::arg("v")) 28 | .def("remove", [](s& smplx, const v& vtx){ 29 | smplx.remove(vtx); 30 | return smplx; 31 | }, "removes a vertex", py::arg("v")) 32 | .def("back", &s::back, "last vertex") 33 | .def("front", &s::front, "front vertex") 34 | .def("reserve", &s::reserve, "reserve capacity", py::arg("n")) 35 | .def("clear", &s::clear, "clear the simplex") 36 | .def("dimension", &s::dimension, "dimension of simplex") 37 | .def("__contains__", [](const s &smplx, const v& vtx){ 38 | return std::binary_search(smplx.begin(), smplx.end(), vtx); 39 | }) 40 | .def("__str__", stream_to_string()) 41 | // Essential: keep object alive while iterator exists 42 | .def("__iter__", [](const s &smplx) { return py::make_iterator(smplx.begin(), smplx.end());}, py::keep_alive<0, 1>()) 43 | .def(py::self == py::self) 44 | .def(py::self != py::self) 45 | .def(py::self < py::self); 46 | py::implicitly_convertible, s >(); 47 | py::implicitly_convertible, s >(); 48 | py::implicitly_convertible, s >(); 49 | 50 | wrap_term>(mod, "Term_Simplex_Z2"); 51 | wrap_term>(mod, "Term_Simplex_Z3"); 52 | wrap_term>(mod, "Term_Simplex_Z5"); 53 | 54 | using b = ctl::Simplex_boundary; 55 | py::class_(mod, std::string("Simplex_boundary").c_str()) 56 | //Default no-args constructor 57 | .def(py::init()) 58 | .def("__call__", [](const b &bd, const s& smplx) { 59 | return py::make_iterator(bd.begin(smplx), bd.end(smplx)); 60 | }, py::keep_alive<0, 1>()) 61 | .def("length", [](const b& bd, const s& smplx){ 62 | return bd.length( smplx); 63 | }, "length of the boundary"); 64 | } 65 | -------------------------------------------------------------------------------- /python/wrap_term.hpp: -------------------------------------------------------------------------------- 1 | // Creates a Python class for an `Simplex_boundary`. 2 | template< typename Cell, typename Coefficient> 3 | void wrap_term(py::module &mod, std::string term){ 4 | typedef ctl::Term Term; 5 | py::class_(mod, term.c_str()) 6 | //Default no-args constructor 7 | .def(py::init()) 8 | .def(py::init()) 9 | .def("coefficient", [](const Term& t){ 10 | return t.coefficient(); 11 | }, "coefficient") 12 | .def("cell", [](const Term& t){ 13 | return t.cell(); 14 | }, "cell") 15 | .def(py::self < py::self) 16 | .def(py::self == py::self) 17 | .def("__str__", stream_to_string()) 18 | .def(py::self != py::self); 19 | py::implicitly_convertible, Term >(); 20 | } -------------------------------------------------------------------------------- /python/wrap_vr.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template< typename T> 4 | class Matrix_view { 5 | typedef T* pointer; 6 | typedef T* const const_pointer; 7 | public: 8 | typedef T value_type; 9 | typedef pointer iterator; 10 | typedef const_pointer const_iterator; 11 | typedef T& reference; 12 | typedef typename std::add_const< reference>::type const_reference; 13 | typedef typename std::size_t size_t; 14 | 15 | public: 16 | 17 | Matrix_view( pointer d, size_t m, size_t n): 18 | m_( m), n_( n), data_( d){} 19 | 20 | reference operator() (size_t i, size_t j) { return data_[ at( i, j)]; } 21 | const_reference operator() (size_t i, size_t j) const { return data_[ at( i, j)]; } 22 | 23 | iterator begin() { return data_; } 24 | const_iterator begin() const { return data_; } 25 | 26 | iterator end() { return data_ + m_*n_; } 27 | const_iterator end() const { return data_ + m_*n_; } 28 | 29 | iterator begin( std::size_t i) { return begin() + at( i) ; } 30 | const_iterator begin( std::size_t i) const { return begin() + at( i); } 31 | 32 | iterator end( std::size_t i) { return begin() + at( i+1); } 33 | const_iterator end( std::size_t i) const { return begin() + at( i+1); } 34 | 35 | size_t m() const { return m_; } 36 | size_t n() const { return n_; } 37 | 38 | size_t size() const { return m_; } 39 | size_t capacity() const { return m_*n_; } 40 | pointer data() { return data_; } 41 | const_pointer data() const { return data_; } 42 | 43 | private: 44 | inline size_t at( size_t i, size_t j) const { return i*n_ + j; } 45 | inline size_t at( size_t i) const { return i*n_; } 46 | 47 | private: 48 | size_t m_; 49 | size_t n_; 50 | pointer data_; 51 | }; //end Matrix_view class 52 | 53 | ctl::Simplicial_complex<> 54 | vr_wrapper(py::array_t array, double epsilon, std::size_t dimension) { 55 | auto info = array.request(); 56 | if( info.ndim != 2){ 57 | throw std::runtime_error("Number of dimensions must be two"); 58 | } 59 | Matrix_view view( (double*)info.ptr, info.shape[0], info.shape[1]); 60 | return ctl::vr( view, epsilon, dimension); 61 | } 62 | 63 | // Creates a Python class for an `Abstract_simplex`. 64 | void wrap_vr(py::module &mod){ 65 | mod.def("vr", &vr_wrapper, "compute the vr complex of a set of points. returns list of simplices", py::keep_alive<0,1>()); 66 | } 67 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #eenable_testing() 2 | add_executable( as ctl_test.cpp test_abstract_simplex.cpp) 3 | add_test( "as" as) 4 | add_executable( bt ctl_test.cpp test_blowup_tool.cpp) 5 | add_test( "bt" bt) 6 | 7 | add_executable( chain ctl_test.cpp test_chain.cpp) 8 | add_test( "chain" chain) 9 | add_executable( cg ctl_test.cpp test_cover_generation.cpp) 10 | add_test( "covers" cg) 11 | #add_executable( ct ctl_test.cpp test_cover_tool.cpp) 12 | add_executable( cube ctl_test.cpp test_cube.cpp) 13 | add_test( "cube" cube) 14 | add_executable( ccc ctl_test.cpp test_cubical_chain_complex.cpp) 15 | add_test( "cc" ccc) 16 | add_executable( filt ctl_test.cpp test_filtration.cpp) 17 | add_test( "filtration" filt) 18 | add_executable( ff ctl_test.cpp test_finite_field.cpp) 19 | add_test( "ff" ff) 20 | add_executable( os ctl_test.cpp test_one_skeleton.cpp) 21 | add_test( "os" os) 22 | add_executable( pc ctl_test.cpp test_product_cell.cpp) 23 | add_test( "pc" pc) 24 | #add_executable( scc ctl_test.cpp test_simplicial_chain_complex.cpp) 25 | #add_executable( vr ctl_test.cpp test_vr.cpp) 26 | -------------------------------------------------------------------------------- /tests/ctl_test.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 8 | -------------------------------------------------------------------------------- /tests/test_abstract_simplex.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | //STL 7 | #include 8 | 9 | //CTL 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | TEST_CASE("DefaultConstruct", "[simplex]"){ 17 | typedef ctl::Abstract_simplex Simplex; 18 | 19 | Simplex s; 20 | REQUIRE(s.size() == 0); 21 | } 22 | 23 | TEST_CASE("InsertCopy", "[simplex]"){ 24 | typedef ctl::Abstract_simplex Simplex; 25 | 26 | Simplex s; 27 | s.insert( 2); 28 | s.insert( 1); 29 | s.insert( 4); 30 | s.insert( 3); 31 | Simplex c( s); 32 | REQUIRE( c == s); 33 | } 34 | 35 | TEST_CASE("InitializerListAndRemove", "[simplex]"){ 36 | typedef ctl::Abstract_simplex Simplex; 37 | 38 | Simplex t( {1,2,5,5,4}); 39 | Simplex s; 40 | s.insert( 1); s.insert( 2); s.insert( 4); s.insert( 5); 41 | REQUIRE( s==t); 42 | t.insert( {8,9,10} ); 43 | t.remove( 5); 44 | REQUIRE(t.size() == 6); 45 | t.remove( t.begin()+2, t.begin()+4); 46 | REQUIRE(t.size() == 4); 47 | } 48 | 49 | TEST_CASE("SimplexBoundary", "[simplex]"){ 50 | typedef ctl::Abstract_simplex Simplex; 51 | typedef ctl::Simplex_boundary Boundary; 52 | 53 | Boundary b; 54 | Simplex s{1,2,3}; 55 | std::vector< Simplex> bd{ {2,3},{1,3},{1,2}}; 56 | for (auto i = b.begin( s); i != b.end( s); ++i){ 57 | REQUIRE(std::find( bd.begin(), bd.end(), i->cell()) != bd.end()); 58 | } 59 | } 60 | 61 | TEST_CASE("SelfAssignmentComparison", "[simplex]"){ 62 | typedef ctl::Abstract_simplex Simplex; 63 | 64 | Simplex s{ 3,4,5}; 65 | s = s; 66 | REQUIRE(s==s); 67 | } 68 | -------------------------------------------------------------------------------- /tests/test_blowup_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2010 3 | ******************************************************************************* 4 | * BSD-3 5 | ******************************************************************************* 6 | * NOTES 7 | * 8 | * 9 | *******************************************************************************/ 10 | 11 | #include 12 | //STL 13 | #include 14 | #include 15 | #include 16 | 17 | //TBB 18 | #include 19 | 20 | //CTL 21 | #include 22 | 23 | 24 | 25 | template 26 | void factor_blowup(const Blowup & blowup, 27 | const Complex & complex2, 28 | const Nerve & complex1){ 29 | typedef typename Blowup::const_iterator Blowup_iterator; 30 | 31 | Nerve new_complex1; 32 | Complex new_complex2; 33 | for (Blowup_iterator product_cell = blowup.begin(); 34 | product_cell != blowup.end(); 35 | ++product_cell){ 36 | //get the cell without any reference to the blowup complex 37 | new_complex1.insert_open_cell(product_cell->first.first->first); 38 | new_complex2.insert_open_cell(product_cell->first.second->first); 39 | } 40 | REQUIRE(complex1== new_complex1); 41 | REQUIRE(complex2== new_complex2); 42 | } 43 | 44 | TEST_CASE("Build", "[blowup]"){ 45 | //1) Build a blowup complex 46 | //2) Test a bunch of stuff 47 | } 48 | -------------------------------------------------------------------------------- /tests/test_chain.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | 7 | #include 8 | //STL 9 | #include 10 | #include 11 | #include 12 | 13 | //CTL 14 | #include 15 | 16 | //Catch 17 | 18 | 19 | 20 | TEST_CASE("ChainTest","[chain]"){ 21 | 22 | //We build a simplicial chain complex with Z2 coefficients 23 | //typedef ctl::Abstract_simplex Simplex; 24 | //typedef ctl::Finite_field< 2> Z2; 25 | typedef ctl::Simplex_boundary Boundary; 26 | typedef ctl::Cell_complex< Boundary> Complex; 27 | typedef Complex::Cell Cell; 28 | typedef ctl::Complex_boundary< Complex> Complex_boundary; 29 | typedef Complex_boundary::Term Term; 30 | //typedef ctl::Filtration< Complex, ctl::Id_less> Filtration; 31 | typedef ctl::Chain< Term, ctl::Term_cell_less< ctl::Id_less> > Chain; 32 | 33 | Complex complex; 34 | ctl::Timer timer; 35 | Cell s( {1,2,3,4,5,6} ); 36 | Cell t( {1,2,3,4,5,11} ); 37 | complex.insert_closed_cell( s); 38 | complex.insert_closed_cell( t); 39 | 40 | Complex_boundary bd( complex); 41 | auto complex_s = complex.find_cell( s); 42 | auto complex_t = complex.find_cell( t); 43 | Chain bds( bd.begin( complex_s), bd.end( complex_s)); 44 | Chain bdt( bd.begin( complex_t), bd.end( complex_t)); 45 | auto bdsandt = bds+bdt; 46 | REQUIRE(bdsandt.size()==10); 47 | 48 | constexpr int N = 600000; 49 | Chain temp; 50 | for( int i = 0; i < N; ++i){ 51 | bds.scaled_add( 1, bdt, temp); 52 | Chain bds( bd.begin( complex_s), bd.end( complex_s)); 53 | Chain bdt( bd.begin( complex_t), bd.end( complex_t)); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /tests/test_cover_generation.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _CTL_COVER_TEST_H_ 2 | #define _CTL_COVER_TEST_H_ 3 | /******************************************************************************* 4 | * Copyright (C) Ryan H. Lewis 2011 5 | ******************************************************************************* 6 | * BSD-3 7 | ******************************************************************************/ 8 | 9 | #include 10 | #include 11 | 12 | namespace ctl{ 13 | namespace parallel { 14 | template 15 | void covered_complex(Complex & complex){ 16 | typedef typename Complex::iterator cell_iterator; 17 | typedef typename Complex::Cell Cell; 18 | typedef typename Complex::Data Data; 19 | for (cell_iterator it = complex.begin(); it != complex.end(); ++it){ 20 | const Cell & cell = it->first; 21 | Data & data = it->second; 22 | REQUIRE(data.data() != Data().data()); 23 | } 24 | } 25 | 26 | template 27 | void sheets_closed(Complex & complex){ 28 | typedef typename Complex::iterator cell_iterator; 29 | typedef typename Complex::Data Data; 30 | typedef typename Complex::Cell Cell; 31 | typedef typename ctl::Complex_boundary< Complex, cell_iterator> 32 | Boundary; 33 | Boundary boundary(complex); 34 | typedef typename Boundary::const_iterator Boundary_iterator; 35 | for (cell_iterator i = complex.begin(); i != complex.end(); ++i){ 36 | const Cell & data = i->second.data()->first; 37 | for(Boundary_iterator j = boundary.begin( i); 38 | j != boundary.end( i); ++j){ 39 | const Data & face_data = j->get_cell()->second; 40 | const Cell & face = face_data.data()->first; 41 | const Cell & face_cell = j->get_cell()->first; 42 | REQUIRE(std::includes(face.begin(), face.end(), 43 | data.begin(), data.end())==true); 44 | } 45 | } 46 | } 47 | 48 | } //namespace parallel 49 | } //namespace ctl 50 | 51 | #endif //_CTL_COVER_TEST_H_ 52 | -------------------------------------------------------------------------------- /tests/test_cover_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2010 3 | ******************************************************************************* 4 | * BSD-3 5 | ****************************************************************************** 6 | * NOTES 7 | *******************************************************************************/ 8 | 9 | #include 10 | //CTL 11 | #include 12 | 13 | //BOOST 14 | #include 15 | 16 | //STL 17 | #include 18 | #include 19 | #include 20 | 21 | //TBB 22 | #include 23 | 24 | namespace po = boost::program_options; 25 | 26 | // Complex type 27 | typedef ctl::Abstract_simplex Cell; 28 | typedef ctl::Finite_field< 2> Z2; 29 | typedef ctl::Simplex_boundary Simplex_boundary; 30 | typedef ctl::parallel::Chain_complex< Cell, Simplex_boundary, 31 | ctl::parallel::Nerve_data> Nerve; 32 | typedef ctl::parallel::Filtration< Nerve, ctl::Cell_less> Nerve_filtration; 33 | 34 | typedef Nerve::iterator Nerve_iterator; 35 | typedef ctl::parallel::Cover_data< Nerve_iterator > Cover_data; 36 | typedef ctl::Chain_complex< Cell, Simplex_boundary, Cover_data> Complex; 37 | 38 | typedef Complex::iterator Complex_iterator; 39 | typedef Complex::const_iterator Complex_const_iterator; 40 | typedef ctl::Cell_less Complex_less; 41 | 42 | typedef ctl::parallel::Filtration< Complex, Complex_less> Complex_filtration; 43 | 44 | typedef ctl::Timer Timer; 45 | typedef ctl::parallel::Cover_stats< Timer> Stats; 46 | 47 | template 48 | void process_args( int & argc, char *argv[],Variable_map & vm){ 49 | //parse command line options 50 | po::options_description desc( "Usage: tp [options] input-file num-parts"); 51 | desc.add_options() 52 | ( "help", "Display this message") 53 | ( "input-file", "input .asc file to parse") 54 | ( "num-parts", "specify partition size") 55 | ( "num-threads", po::value()->default_value(-1), 56 | "specify number of threads"); 57 | po::positional_options_description p; 58 | p.add( "input-file",1); 59 | p.add( "num-parts",1); 60 | po::store( po::command_line_parser( argc,argv) 61 | .options( desc) 62 | .positional( p) 63 | .run(), 64 | vm); 65 | po::notify( vm); 66 | if ( vm.count( "help")){ 67 | std::cout << desc << std::endl; 68 | std::exit( 0); 69 | } 70 | if ( vm.count( "input-file") != 1 || vm.count( "num-parts") != 1){ 71 | std::cout << desc << std::endl; 72 | std::exit( -1); 73 | } 74 | } 75 | 76 | int main( int argc, char *argv[]){ 77 | po::variables_map vm; 78 | process_args( argc, argv, vm); 79 | size_t num_parts = atoi( vm[ "num-parts"].as< std::string>().c_str()); 80 | 81 | //setup some variables 82 | std::string full_complex_name = vm[ "input-file"].as< std::string>(); 83 | std::string complex_name( full_complex_name); 84 | std::string binary_name( argv[ 0]); 85 | 86 | int num_threads = vm[ "num-threads"].as< int>(); 87 | size_t found = complex_name.rfind( '/'); 88 | if ( found != std::string::npos){ 89 | complex_name.replace( 0, found+1, ""); 90 | } 91 | 92 | Complex complex; 93 | Nerve nerve; 94 | Stats stats; 95 | // Read the chain_complex in 96 | ctl::read_complex( full_complex_name, complex); 97 | if (num_threads != -1){ 98 | tbb::task_scheduler_init init( num_threads); 99 | }else{ 100 | tbb::task_scheduler_init init; 101 | } 102 | 103 | stats.timer.start(); 104 | Complex_filtration complex_filtration( complex); 105 | stats.timer.stop(); 106 | double filtration_time = stats.timer.elapsed(); 107 | std::cout << "time to filter complex: " << filtration_time << std::endl; 108 | 109 | stats.timer.start(); 110 | ctl::parallel::init_cover_complex( nerve, num_parts); 111 | ctl::parallel::graph_partition_cover( complex_filtration, nerve); 112 | stats.timer.stop(); 113 | double cover_time = stats.timer.elapsed(); 114 | std::cout << "cover time: " << cover_time << std::endl; 115 | Nerve_filtration ordered_nerve( nerve); 116 | 117 | //typedef Nerve_filtration::iterator Iterator; 118 | for(const auto & cell: ordered_nerve){ 119 | std::cout << cell->first << ": " << cell->second.count() << std::endl; 120 | } 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /tests/test_cube.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | 7 | #include 8 | //STL 9 | #include 10 | 11 | //CTL 12 | #include 13 | #include 14 | #include 15 | 16 | TEST_CASE("a","b"){ 17 | } 18 | /* 19 | TEST_CASE("Cube", "[cube]"){ 20 | typedef ctl::Cube Cube; 21 | typedef Cube::Interval Interval; 22 | typedef ctl::Finite_field< 2> Z2; 23 | typedef ctl::Cube_boundary< Z2> Boundary; 24 | Cube s; 25 | s.insert( Interval( 2, 3) ); 26 | s.insert( Interval( 3, 3) ); 27 | Cube c( s); 28 | REQUIRE(c==s); 29 | Cube t( {{1,2},{4,5},{4,4}}); 30 | t.insert( {{8,9},{9,10}, {11,11}} ); 31 | t.remove( {11,11} ); 32 | t.remove( t.begin(), t.begin()+1); 33 | Boundary b; 34 | for (auto i = b.begin( t); i != b.end( t); ++i){ 35 | auto j = (*i).cell(); 36 | } 37 | } 38 | */ 39 | -------------------------------------------------------------------------------- /tests/test_cubical_chain_complex.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | 7 | #include 8 | 9 | //STL 10 | #include 11 | 12 | //CTL 13 | #include 14 | #include 15 | 16 | //chain_complex 17 | #include 18 | #include 19 | 20 | //We build a simplicial chain complex with Z2 coefficients 21 | 22 | typedef ctl::Finite_field< 3> Z3; 23 | typedef ctl::Cube Cube; 24 | typedef ctl::Cube_boundary Cube_boundary; 25 | typedef ctl::Cell_complex< Cube_boundary> Cubical_complex; 26 | typedef Cubical_complex::Cell_boundary Cubical_cell_boundary; 27 | typedef ctl::Complex_boundary< Cubical_complex> Cubical_complex_boundary; 28 | typedef Cubical_complex_boundary::const_iterator cubical_boundary_iterator; 29 | /* 30 | TEST_CASE("EqualityTest","[cubical complex]"){ 31 | Cubical_complex complex; 32 | Cubical_complex c2( complex); 33 | REQUIRE(complex==c2); 34 | } 35 | 36 | 37 | TEST_CASE("FindCellWorks","[cubical complex]"){ 38 | Cubical_complex complex; 39 | for( auto i = complex.begin(); i != complex.end(); ++i){ 40 | REQUIRE( complex.find_cell( i->first) == i); 41 | } 42 | }*/ 43 | -------------------------------------------------------------------------------- /tests/test_filtration.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | 7 | #include 8 | //STL 9 | #include 10 | 11 | //CTL 12 | //abstract_simplex 13 | #include 14 | #include 15 | 16 | //chain_complex 17 | #include 18 | 19 | //filtration 20 | #include 21 | #include 22 | //timer 23 | #include 24 | 25 | //GTest 26 | 27 | 28 | //We build a simplicial chain complex with Z2 coefficients 29 | typedef ctl::Abstract_simplex Simplex; 30 | typedef ctl::Finite_field< 2> Z2; 31 | typedef ctl::Simplex_boundary Boundary; 32 | typedef ctl::Cell_complex< Boundary> Complex; 33 | typedef Complex::Cell Cell; 34 | typedef ctl::Graded_cell_complex< Complex> Filtration_cell_less; 35 | typedef ctl::Timer Timer; 36 | typedef ctl::Graded_cell_complex< Complex, ctl::Id_less> Filtration_id_less; 37 | 38 | template< typename Filtration> 39 | bool is_sorted( const Filtration & f){ 40 | typedef typename Filtration::Less Less; 41 | Less less; 42 | auto last = f.begin(); 43 | for( auto i = ++f.begin(); i < f.end(); ++i, ++last){ 44 | if (!less( *last, *i)){ return false; } 45 | } 46 | return true; 47 | } 48 | 49 | TEST_CASE( "Filtration_cell_less", "TotalOrderWorking"){ 50 | Complex c; 51 | Timer t; 52 | t.start(); 53 | Cell s( {1,2,3,4,5,6,8,9,10} ); 54 | c.insert_closed_cell( s); 55 | REQUIRE(511 == c.size()); 56 | Filtration_cell_less f1( c); 57 | REQUIRE(f1.size() == c.size()); 58 | t.elapsed(); 59 | REQUIRE( is_sorted( f1) == true); 60 | } 61 | TEST_CASE( "Filtration_id_less", "TotalOrderWorking"){ 62 | Complex c; 63 | Timer t; 64 | t.start(); 65 | Cell s( {1,2,3,4,5,6,8,9,10} ); 66 | c.insert_closed_cell( s); 67 | t.elapsed(); 68 | t.start(); 69 | Filtration_id_less f2( c); 70 | t.elapsed(); 71 | REQUIRE( true == is_sorted( f2)); 72 | } 73 | -------------------------------------------------------------------------------- /tests/test_finite_field.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ******************************************************************************* 3 | * Copyright (C) Ryan H. Lewis 2014 4 | ******************************************************************************* 5 | *******************************************************************************/ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | TEST_CASE("Z2", "[finite-field]"){ 12 | typedef ctl::Finite_field< 2> Z2; 13 | Z2 a( 1); 14 | REQUIRE(a+a == Z2(0)); 15 | } 16 | 17 | TEST_CASE("Z3", "[finite-field]"){ 18 | typedef ctl::Finite_field< 3> Z3; 19 | Z3 b( 1); 20 | REQUIRE (b+b+b == Z3( 0)); 21 | Z3 bneg( -1); 22 | REQUIRE (-1*b == bneg); 23 | } 24 | 25 | TEST_CASE("Z11", "[finite-field]"){ 26 | typedef ctl::Finite_field< 11> Z11; 27 | Z11 c( 1); 28 | REQUIRE(c*11 == Z11(0)); 29 | for( std::size_t i = 1; i < 11; ++i){ 30 | c = i; 31 | REQUIRE(c*ctl::inverse(c)==Z11(1)); 32 | } 33 | for( std::size_t i = 1; i < 11; ++i){ 34 | c = i; 35 | REQUIRE(c/c == Z11(1)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/test_one_skeleton.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2011 3 | * 4 | ******************************************************************************* 5 | * BSD-3 6 | *******************************************************************************/ 7 | #include 8 | 9 | 10 | //STL 11 | #include 12 | 13 | //Project 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | 20 | TEST_CASE("GrabsOnlyGraph", "[one-skeleton]"){ 21 | typedef ctl::Abstract_simplex Simplex; 22 | typedef ctl::Simplex_boundary Simplex_boundary; 23 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 24 | 25 | Complex complex, complex1; 26 | 27 | // Types for METIS CSR & map 28 | typedef Complex::Cell Simplex; 29 | typedef Simplex::vertex_type vertex_type; 30 | typedef std::vector< unsigned int> Vector; 31 | std::vector< vertex_type> index_to_vertex_map, i1; 32 | 33 | // Results 34 | Vector neighbors, n1, offsets, o1; 35 | 36 | complex.insert_closed_cell( {1,2,3}); 37 | complex1.insert_closed_cell( {1,2}); 38 | complex1.insert_closed_cell( {1,3}); 39 | complex1.insert_closed_cell( {2,3}); 40 | 41 | // Extract out 1-skeleton in CSR format 42 | one_skeleton( complex, neighbors, offsets, index_to_vertex_map); 43 | one_skeleton( complex1, n1, o1, i1); 44 | REQUIRE(true ==std::is_permutation( n1.begin(), n1.end(), neighbors.begin())); 45 | REQUIRE(true ==std::is_permutation( o1.begin(), o1.end(), offsets.begin())); 46 | REQUIRE(true ==std::is_permutation( i1.begin(), i1.end(), index_to_vertex_map.begin())); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /tests/test_product_cell.cpp: -------------------------------------------------------------------------------- 1 | // STL 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | // Project 8 | #include 9 | 10 | TEST_CASE( "IteratorConstructors", "[product-cell]"){ 11 | 12 | //typedef ctl::Abstract_simplex Simplex; 13 | typedef ctl::Simplex_boundary Boundary; 14 | typedef ctl::Cell_complex< Boundary> Complex; 15 | // product type 16 | typedef ctl::Iterator_product_cell< Complex::iterator, Complex::iterator> Product; 17 | 18 | Complex c1, c2; 19 | Complex::Cell s1, s2; 20 | 21 | // Two starting complexes: triangle 012, and edge 34 22 | s1.insert( 0); 23 | s1.insert( 1); 24 | s1.insert( 2); 25 | 26 | s2.insert( 3); 27 | s2.insert( 4); 28 | 29 | c1.insert_closed_cell( s1); 30 | c2.insert_closed_cell( s2); 31 | 32 | auto i1 = c1.find_cell( s1); 33 | auto i2 = c2.find_cell( s2); 34 | 35 | // first product 36 | Product p1( i1, i2); 37 | REQUIRE( p1.dimension() == 3); 38 | // copy constructor 39 | Product p2( p1); 40 | REQUIRE(p2 == p1); 41 | 42 | // assignment 43 | Product p3 = p1; 44 | REQUIRE(p3== p1); 45 | REQUIRE(p2== p3); 46 | REQUIRE(p3.dimension() == 3); 47 | 48 | // second one 49 | Product p4( i2, i1); 50 | 51 | REQUIRE( p4< p2); 52 | } 53 | 54 | TEST_CASE( "Constructors", "[product-cell]"){ 55 | 56 | //typedef ctl::Abstract_simplex Simplex; 57 | typedef ctl::Simplex_boundary Boundary; 58 | typedef ctl::Cell_complex< Boundary> Complex; 59 | // product type 60 | typedef ctl::Product_cell< Complex::Cell, Complex::Cell> Product; 61 | 62 | Complex::Cell s1, s2; 63 | 64 | // Two starting complexes: triangle 012, and edge 34 65 | s1.insert( 0); 66 | s1.insert( 1); 67 | s1.insert( 2); 68 | 69 | s2.insert( 3); 70 | s2.insert( 4); 71 | 72 | // first product 73 | Product p1( s1, s2); 74 | REQUIRE( p1.dimension() == 3); 75 | // copy constructor 76 | Product p2( p1); 77 | REQUIRE(p2 == p1); 78 | 79 | // assignment 80 | Product p3 = p1; 81 | REQUIRE(p3== p1); 82 | REQUIRE(p2== p3); 83 | REQUIRE(p3.dimension() == 3); 84 | 85 | // second one 86 | Product p4( s2, s1); 87 | 88 | REQUIRE( p4< p2); 89 | } 90 | 91 | TEST_CASE("ProductBoundary", "[product-cell]"){ 92 | //typedef ctl::Abstract_simplex Simplex; 93 | typedef ctl::Simplex_boundary Simplex_boundary; 94 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 95 | // product type 96 | typedef ctl::Product_cell< Complex::Cell, Complex::Cell> Product; 97 | 98 | Complex::Cell s1, s2; 99 | 100 | // Two starting complexes: triangle 012, and edge 34 101 | s1.insert( 0); 102 | s1.insert( 1); 103 | s1.insert( 2); 104 | 105 | s2.insert( 3); 106 | s2.insert( 4); 107 | s2.insert( 5); 108 | 109 | // first product 110 | Product p1( s1, s2); 111 | // copy constructor 112 | Product p2( p1); 113 | 114 | typedef ctl::Product_boundary< Simplex_boundary, Simplex_boundary> Product_boundary; 115 | 116 | // now the product 117 | Product_boundary boundary; 118 | 119 | // regularity 120 | auto j = boundary.begin( p1); // assignable 121 | REQUIRE(j == boundary.begin( p1)); 122 | for(; j != boundary.end( p1); *j++){ 123 | std::cout << *j << std::endl; 124 | } 125 | } 126 | 127 | 128 | 129 | TEST_CASE("IteratorProductBoundary", "[product-cell]"){ 130 | //typedef ctl::Abstract_simplex Simplex; 131 | typedef ctl::Simplex_boundary Simplex_boundary; 132 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 133 | // product type 134 | typedef ctl::Iterator_product_cell< Complex::iterator, Complex::iterator> Product; 135 | 136 | Complex c1, c2; 137 | Complex::Cell s1, s2; 138 | 139 | // Two starting complexes: triangle 012, and edge 34 140 | s1.insert( 0); 141 | s1.insert( 1); 142 | s1.insert( 2); 143 | 144 | s2.insert( 3); 145 | s2.insert( 4); 146 | 147 | c1.insert_closed_cell( s1); 148 | c2.insert_closed_cell( s2); 149 | 150 | auto i1 = c1.find_cell( s1); 151 | auto i2 = c2.find_cell( s2); 152 | 153 | // first product 154 | Product p1( i1, i2); 155 | // copy constructor 156 | Product p2( p1); 157 | 158 | // Now, onto boundary 159 | typedef ctl::Complex_boundary< Complex> Boundary; 160 | typedef ctl::Iterator_product_boundary< Product, Boundary, Boundary> Product_boundary; 161 | 162 | Boundary b1( c1); 163 | Boundary b2( c2); 164 | 165 | // now the product 166 | Product_boundary boundary( b1, b2); 167 | 168 | // regularity 169 | Product_boundary::const_iterator j; // default 170 | j = boundary.begin( p1); // assignable 171 | REQUIRE(j == boundary.begin( p1)); 172 | } 173 | -------------------------------------------------------------------------------- /tests/test_simplicial_chain_complex.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | *******************************************************************************/ 4 | 5 | #include 6 | //STL 7 | #include 8 | 9 | //CTL 10 | //abstract_simplex 11 | #include 12 | #include 13 | 14 | //Chain_complex 15 | #include 16 | #include 17 | 18 | //We build a simplicial chain complex with Z2 coefficients 19 | 20 | typedef ctl::Abstract_simplex Simplex; 21 | typedef ctl::Finite_field< 3> Z3; 22 | typedef ctl::Simplex_boundary Simplex_boundary; 23 | typedef ctl::Chain_complex< Simplex, Simplex_boundary> Simplicial_complex; 24 | typedef Simplicial_complex::Cell Cell; 25 | typedef ctl::Complex_boundary< Simplicial_complex> Simplicial_complex_boundary; 26 | 27 | typedef Simplicial_complex_boundary::const_iterator simplicial_boundary_iterator; 28 | 29 | 30 | int main( int argc, char** argv){ 31 | Simplicial_complex complex; 32 | Cell s( {1,2,3,4} ); 33 | auto pair = complex.insert_closed_cell( s); 34 | std::cout << pair.second << " cells inserted!" << std::endl; 35 | std::cout << "complex is " << 36 | ((complex.is_closed())? "closed":"not closed") << std::endl; 37 | std::cout << complex << std::endl; 38 | 39 | Simplicial_complex_boundary b( complex); 40 | Simplicial_complex_boundary copyd( b); 41 | Simplicial_complex_boundary moved( std::move( copyd)); 42 | for( auto i = complex.begin(); i != complex.end(); ++i){ 43 | std::cout << "boundary test: " << ctl::delta << "(" 44 | << i->first << ")" << std::endl; 45 | std::cout << "boundary length: " << b.length( i) << std::endl; 46 | for( simplicial_boundary_iterator j = b.begin( i); j != b.end( i); ++j){ 47 | std::cout << j->cell()->first << " "; 48 | } 49 | std::cout << std::endl; 50 | } 51 | std::ofstream out( "test.asc"); 52 | complex.write( out); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /tests/test_vr.cpp: -------------------------------------------------------------------------------- 1 | #define CTL_USE_CITY 2 | //STL 3 | #include 4 | #include 5 | 6 | //CTL 7 | //Utility 8 | #include 9 | #include 10 | 11 | 12 | //Types for Points 13 | //#include 14 | 15 | //Types for Graphs 16 | #include 17 | 18 | //Types for Building a Simplicial Chain Complex 19 | //Abstract Simplex 20 | #include 21 | #include 22 | #include 23 | 24 | //Chain Complex 25 | #include 26 | #include 27 | #include 28 | 29 | //VR Construction 30 | #include 31 | #include 32 | 33 | //Graph 34 | typedef typename ctl::Nbhd_graph<> Graph; 35 | 36 | //Simplex 37 | typedef ctl::Abstract_simplex Simplex; 38 | typedef ctl::Finite_field< 2> Z2; 39 | typedef ctl::Simplex_boundary Simplex_boundary; 40 | 41 | //Chain Complex 42 | typedef ctl::Chain_complex< Simplex, Simplex_boundary> Complex; 43 | 44 | 45 | // temporary solution until we build points.h 46 | typedef std::vector Point; 47 | typedef std::vector Points; 48 | 49 | int main (int argc, char* argv[]) { 50 | if( argc != 4){ 51 | std::cerr << "Usage: " << argv[ 0] 52 | << " filename.dat epsilon dimension" << std::endl; 53 | return 0; 54 | } 55 | ctl::Timer clock; 56 | double epsilon = atof( argv[ 2]); 57 | std::size_t dimension = atoi( argv[ 3]); 58 | 59 | Points points; 60 | std::ifstream in; 61 | ctl::open_file( in, argv[ 1]); 62 | 63 | Point point; 64 | double coordinate; 65 | std::size_t line_num = 0; 66 | while( true){ 67 | std::string line; 68 | ctl::get_line( in, line, line_num); 69 | if( in.eof() ) break; 70 | std::stringstream ss( line); 71 | while( ss.good()){ 72 | ss >> coordinate; 73 | point.push_back( coordinate); 74 | } 75 | points.push_back( point); 76 | point.clear(); 77 | } 78 | clock.start(); 79 | Graph graph; 80 | ctl::all_pairs::construct_graph(points, epsilon, graph); 81 | clock.stop(); 82 | std::cerr << "Graph: " << boost::num_vertices( graph) << ", " 83 | << boost:: num_edges( graph) << std::endl; 84 | std::cerr << "Graph construction: " << clock.elapsed() << std::endl; 85 | clock.start(); 86 | Complex complex; 87 | ctl::incremental_vr(graph, complex, dimension); 88 | clock.stop(); 89 | std::cerr << "Incremental construction: " << clock.elapsed() << std::endl; 90 | std::cerr << "Number of simplices: " << complex.size() << std::endl; 91 | std::cerr << "dimension of complex: " << complex.dimension() << std::endl; 92 | // std::cerr << "Complex: " << complex << std::endl; 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if( Boost_FOUND) 2 | add_executable(persistence persistence.cpp) 3 | install( TARGETS persistence RUNTIME DESTINATION bin) 4 | 5 | if( APPLE) 6 | target_link_libraries( persistence ${Boost_LIBRARIES} ${DSO_FIX}) 7 | endif( APPLE) 8 | if( ${CMAKE_SYSTEM_NAME} MATCHES "Linux") 9 | target_link_libraries( persistence ${Boost_LIBRARIES} ${DSO_FIX}) 10 | endif( ${CMAKE_SYSTEM_NAME} MATCHES "Linux") 11 | endif() 12 | 13 | if( ANN_FOUND) 14 | add_executable(ngraph ngraph.cpp) 15 | target_link_libraries( ngraph ${ANN_LIBRARIES}) 16 | install( TARGETS ngraph RUNTIME DESTINATION bin) 17 | endif() 18 | 19 | add_executable(duplicate build_blobs.cpp) 20 | install( TARGETS duplicate RUNTIME DESTINATION bin) 21 | 22 | add_executable(build_clique clique_tool.cpp) 23 | install( TARGETS build_clique RUNTIME DESTINATION bin) 24 | 25 | if( Boost_FOUND) 26 | add_executable(euler euler_tool.cpp) 27 | target_link_libraries( euler ${Boost_LIBRARY_PATH} ${Boost_LIBRARIES} ${DSO_FIX}) 28 | install( TARGETS euler RUNTIME DESTINATION bin) 29 | endif() 30 | 31 | add_executable(complex_size complex_size.cpp) 32 | install( TARGETS complex_size RUNTIME DESTINATION bin) 33 | 34 | if( METIS_FOUND AND Boost_FOUND) 35 | add_executable (oneskeleton complex_to_graph_tool.cpp) 36 | target_link_libraries( oneskeleton ${METIS_LIBRARIES} ${Boost_LIBRARIES} ${DSO_FIX}) 37 | install( TARGETS oneskeleton RUNTIME DESTINATION bin) 38 | endif() 39 | 40 | add_executable (wghtomet graph_to_metis_tool.cpp) 41 | install( TARGETS wghtomet RUNTIME DESTINATION bin) 42 | 43 | add_executable (metowgh metis_to_graph_tool.cpp) 44 | install( TARGETS metowgh RUNTIME DESTINATION bin) 45 | 46 | if( METIS_FOUND AND Boost_FOUND) 47 | add_executable (gpcover gpcover_tool.cpp) 48 | target_link_libraries( gpcover ${METIS_LIBRARIES} ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${DSO_FIX}) 49 | install( TARGETS gpcover RUNTIME DESTINATION bin) 50 | endif() 51 | 52 | if( Boost_FOUND) 53 | add_executable (ctl2phat phat_tool.cpp) 54 | target_link_libraries( ctl2phat ${Boost_LIBRARIES}) 55 | install( TARGETS ctl2phat RUNTIME DESTINATION bin) 56 | endif() 57 | 58 | if( Boost_FOUND AND METIS_FOUND AND TBB_FOUND) 59 | add_executable (concurrent_homology concurrent_homology_tool) 60 | target_link_libraries (concurrent_homology ${Boost_LIBRARY_PATH} 61 | ${TBB_LIBRARY_PATH} ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${METIS_LIBRARIES} ${DSO_FIX}) 62 | install( TARGETS concurrent_homology RUNTIME DESTINATION bin) 63 | endif() 64 | 65 | if( Boost_FOUND AND METIS_FOUND AND TBB_FOUND) 66 | add_executable (cover_homology cover_homology_tool) 67 | target_link_libraries (cover_homology ${Boost_LIBRARIES} ${METIS_LIBRARIES} ${TBB_LIBRARIES} ${DSO_FIX}) 68 | install( TARGETS cover_homology RUNTIME DESTINATION bin) 69 | endif() 70 | 71 | if( Boost_FOUND AND ANN_FOUND) 72 | add_executable (vr vr.cpp) 73 | target_link_libraries( vr ${Boost_LIBRARIES} ${ANN_LIBRARIES} ${DSO_FIX}) 74 | endif() 75 | 76 | if (Boost_FOUND) 77 | add_executable (write_filtration write_filtration_tool.cpp) 78 | target_link_libraries( write_filtration ${Boost_LIBRARIES} ${DSO_FIX}) 79 | install( TARGETS write_filtration RUNTIME DESTINATION bin) 80 | endif() 81 | -------------------------------------------------------------------------------- /tools/alpha.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appliedtopology/ctl/b610fa4a9afc439b071457dd0c9d1a823ac1537a/tools/alpha.cpp -------------------------------------------------------------------------------- /tools/build_blobs.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | // build_blobs.cpp 7 | // Ryan Lewis 8 | // July 8, 2011 9 | // STL 10 | #include 11 | #include 12 | #include 13 | 14 | // Project 15 | #include 16 | #include 17 | #include 18 | 19 | typedef ctl::Abstract_simplex Simplex; 20 | typedef ctl::Finite_field< 2> Z2; 21 | typedef ctl::Simplex_boundary Simplex_Boundary; 22 | typedef ctl::Cell_complex< Simplex_Boundary> Complex; 23 | 24 | void usage( const char* argv){ 25 | std::cerr << "Usage: " 26 | << argv << " input_name num_duplicates (=2) dim_of_connection=[no connection = default, 1..d specifies a cell of that dimension] " << std::endl; 27 | std::exit(1); 28 | } 29 | 30 | int main(int argc, char *argv[]) { 31 | if( argc < 2) { usage( argv[ 0]); } 32 | std::size_t num=2; 33 | if(argc==3 || argc == 4){ 34 | num=atoi(argv[ 2]); 35 | if (num < 2){ usage( argv[ 0]); } 36 | } 37 | int flag = -1; 38 | if( argc == 4){ 39 | flag = atoi( argv[ 3]); 40 | } 41 | //initial stuff 42 | Complex input_complex, output_complex; 43 | std::ifstream in; 44 | std::string basename( argv[ 1]); 45 | ctl::open_file(in, basename.c_str()); 46 | //in >> input_complex; 47 | std::cout << "original complex size: " 48 | << input_complex.size() << std::endl; 49 | output_complex = input_complex; 50 | size_t found = basename.rfind('.'); 51 | if (found != std::string::npos){ 52 | basename.replace( found, basename.size()-1, ""); 53 | } 54 | 55 | typedef typename Complex::Cell Cell; 56 | typedef typename Cell::value_type Value; 57 | //compute num_vertices 58 | Value max_vertex_name= *(input_complex.begin()->first.rbegin()); 59 | std::size_t num_vertices=0; 60 | for(auto cell: input_complex){ 61 | //simplices are stored sorted 62 | typename Complex::Cell::value_type cur = *(cell.first.rbegin()); 63 | if(cell.first.dimension() == 0){ 64 | if( max_vertex_name < cur){ 65 | max_vertex_name = cur; 66 | } 67 | ++num_vertices; 68 | } 69 | } 70 | std::cout << "flag: " << flag << std::endl; 71 | std::cout << "num_vertices: " << num_vertices << std::endl; 72 | max_vertex_name++; 73 | for ( auto i : input_complex){ 74 | for(std::size_t j = 1; j < num; ++j){ 75 | Cell cell = i.first; 76 | for( auto& vertex_name : cell){ vertex_name+=max_vertex_name*j; } 77 | output_complex.insert_open_cell( cell); 78 | } 79 | } 80 | if (flag > 0 && (std::size_t)flag <= num_vertices) { 81 | for( int i=0; i < (int)num-1; ++i){ 82 | Cell cell = { i*max_vertex_name, (i+1)*max_vertex_name}; 83 | for (int j = 2; j < flag+1; ++j){ 84 | cell.insert( (i+1)*max_vertex_name + (j-1) ); 85 | } 86 | std::cout << "inserting: " << cell << std::endl; 87 | output_complex.insert_closed_cell( cell); 88 | } 89 | } 90 | std::string name( basename); 91 | std::stringstream ss; 92 | ss << "." << num << ".asc"; 93 | name.append(ss.str()); 94 | std::cout << "writing complex: " << name; 95 | std::cout << " of size: " << output_complex.size() << std::endl; 96 | std::ofstream out; 97 | ctl::open_file( out, name.c_str()); 98 | //output_complex.write( out); 99 | out.close(); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /tools/cech.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appliedtopology/ctl/b610fa4a9afc439b071457dd0c9d1a823ac1537a/tools/cech.cpp -------------------------------------------------------------------------------- /tools/clique_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | // build_blobs.cpp 7 | // Ryan Lewis 8 | // July 8, 2011 9 | 10 | //STL 11 | #include 12 | #include 13 | 14 | //CTL 15 | #include 16 | #include 17 | #include 18 | 19 | typedef ctl::Abstract_simplex Simplex; 20 | typedef ctl::Finite_field< 2> Z2; 21 | typedef ctl::Simplex_boundary Simplex_Boundary; 22 | typedef ctl::Cell_complex< Simplex_Boundary> Complex; 23 | 24 | int main(int argc, char *argv[]) { 25 | if( argc < 2) { 26 | std::cerr << "Usage: " << argv[ 0] << " filename num_vertices" << std::endl; 27 | std::exit( 1); 28 | } 29 | //initial stuff 30 | Complex complex; 31 | std::string basename(argv[ 1]); 32 | basename.append(".").append(argv[ 2]).append(".asc"); 33 | std::size_t n = atoi( argv[ 2]); 34 | Simplex cell; 35 | for( std::size_t i = 0; i < n; ++i) { cell.insert(i); } 36 | std::cout << "building VR complex on: " << cell << std::endl; 37 | complex.insert_closed_cell(cell,true); 38 | std::cout << "complex has: " << complex.size() << " simplices" << std::endl; 39 | std::ofstream out; 40 | ctl::open_file(out, basename.c_str()); 41 | //complex.write( out); 42 | ctl::close_file( out); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /tools/complex_size.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2014 3 | *******************************************************************************/ 4 | //#define COMPUTE_BETTI 5 | //#define CTL_USE_MURMUR 6 | #define CTL_USE_CITY 7 | //#define CTL_USE_JENKINS 8 | //#define COMPLEX_DIAGNOSTICS 9 | 10 | #ifdef ZOOM_PROFILE 11 | #include "zoom.h" 12 | #endif 13 | 14 | #ifdef COMPLEX_DIAGNOSTICS 15 | #include "utility/complex_diagnostics.h" 16 | #endif 17 | //CTL 18 | //Types for Building a Simplicial Chain Complex and Filtration 19 | #include 20 | 21 | //STL 22 | #include 23 | 24 | //Build Complex type 25 | typedef ctl::Abstract_simplex Simplex; 26 | typedef ctl::Finite_field< 2> Z2; 27 | typedef ctl::Simplex_boundary Simplex_boundary; 28 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 29 | 30 | template 31 | void process_args(int & argc, char *argv[], String & filename){ 32 | std::string usage = "Usage: complex_size input-file"; 33 | if (argc != 2){ std::cerr << usage << std::endl; exit( 1); } 34 | filename = std::string( argv[ 1]); 35 | } 36 | 37 | int main(int argc, char *argv[]){ 38 | std::string full_complex_name; 39 | process_args(argc, argv, full_complex_name); 40 | 41 | //create some data structures 42 | Complex complex; 43 | ctl::Timer timer; 44 | 45 | // Read the cell_set in 46 | timer.start(); 47 | //ctl::read_complex( full_complex_name, complex); 48 | timer.elapsed(); 49 | std::cout << "I/O Time: " << timer.elapsed() << std::endl; 50 | std::cout << "number of simplices: " << complex.size() << std::endl; 51 | std::cout << "complex dimension: " << complex.dimension() << std::endl; 52 | typedef std::vector< std::size_t> Vector; 53 | Vector counts( complex.dimension()+1, 0); 54 | typedef typename Complex::Cell Cell; 55 | typedef typename Cell::value_type Vertex_type; 56 | 57 | std::size_t complex_bytes=sizeof( Cell)*complex.size() + sizeof( Complex); 58 | for( const auto & cell : complex){ 59 | complex_bytes += sizeof( Vertex_type)*cell.first.capacity(); 60 | counts[ cell.first.dimension()]++; 61 | } 62 | std::cout << "Cells by dimension: " << std::endl; 63 | for( const auto size : counts){ std::cout << size << std::endl; } 64 | std::cout << "Rough estimate of memory used: " 65 | << complex_bytes << " (bytes)" << std::endl; 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /tools/complex_to_graph_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2011 3 | ****************************************************************************** 4 | * BSD-3 5 | *******************************************************************************/ 6 | // STL 7 | #include 8 | #include 9 | #include 10 | #include 11 | // Project 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | //BOOST 23 | #include 24 | #include 25 | 26 | namespace po = boost::program_options; 27 | 28 | // Complex type 29 | typedef ctl::Abstract_simplex Simplex; 30 | typedef ctl::Finite_field< 2> Z2; 31 | typedef ctl::Simplex_boundary Simplex_boundary; 32 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 33 | typedef std::vector index_to_vertex_t; 34 | int main(int argc, char *argv[]) { 35 | //setup options 36 | po::options_description desc("Usage: one_skeleton [options] input_file"); 37 | desc.add_options() 38 | ( "help", "Display this message") 39 | ( "metis", "extract to a metis format") 40 | ( "dot", "extract to a dot format") 41 | ( "metis-index-off", "do not construct a metis vertex index file") 42 | ( "input-file", "input .asc file to parse"); 43 | po::positional_options_description p; 44 | p.add("input-file",-1); 45 | po::variables_map vm; 46 | po::store( 47 | po::command_line_parser(argc,argv).options(desc).positional(p).run(), 48 | vm 49 | ); 50 | po::notify(vm); 51 | if (vm.count("help")){ 52 | std::cout << desc << std::endl; 53 | std::exit( 0); 54 | } 55 | if (vm.count("input-file") != 1){ 56 | std::cout << desc << std::endl; 57 | std::exit( -1); 58 | } 59 | if( (vm.count("metis") || vm.count("metis-index-off")) && vm.count("dot")){ 60 | std::cerr << "improper combination of flags" << std::endl; 61 | } 62 | 63 | // Set up complex 64 | Complex complex; 65 | ctl::Nbhd_graph<> graph; 66 | 67 | // Read the complex in 68 | std::ifstream in; 69 | ctl::open_file( in, vm["input-file"].as< std::string >().c_str()); 70 | //in >> complex; 71 | ctl::close_file( in); 72 | 73 | std::string extension; 74 | std::vector< int> neighbors; //num_vertices+1 75 | std::vector< int> offsets; //2*num_edges 76 | index_to_vertex_t index_to_vertex_map; 77 | 78 | //extract graph 79 | if (vm.count("metis")){ 80 | ctl::one_skeleton( complex, neighbors, offsets, index_to_vertex_map); 81 | extension.append(".met"); 82 | }else{ 83 | ctl::complex_to_graph(complex, graph); 84 | if (vm.count("dot")){ 85 | extension.append(".dot"); 86 | }else{ 87 | extension.append(".ngh"); 88 | } 89 | } 90 | 91 | //make filename 92 | std::string graph_name ( vm["input-file"].as< std::string >()); 93 | std::string index_file ( vm["input-file"].as< std::string >()); 94 | size_t found = graph_name.rfind( '.'); 95 | if (found == std::string::npos){ 96 | graph_name.append(extension); 97 | index_file.append(".idxmet"); 98 | }else{ 99 | graph_name.replace( found, graph_name.size()-1, extension); 100 | index_file.replace( found, index_file.size()-1, ".idxmet"); 101 | } 102 | 103 | //write to a file 104 | std::ofstream out; 105 | ctl::open_file( out,graph_name.c_str()); 106 | if(vm.count("metis")){ 107 | ctl::write_metis( out, offsets, neighbors); 108 | }else if(vm.count("dot")){ 109 | boost::write_graphviz( out, graph); 110 | }else{ 111 | out << graph; 112 | } 113 | ctl::close_file( out); 114 | 115 | //write out a metis index file, if you want to get vertex names back later 116 | if (vm.count("metis") && !vm.count("metis-index-off")){ 117 | std::ofstream index_out; 118 | ctl::open_file( index_out, index_file.c_str()); 119 | int count = 1; 120 | for (index_to_vertex_t::iterator it = index_to_vertex_map.begin(); 121 | it != index_to_vertex_map.end(); 122 | ++it, ++count){ 123 | index_out << count << " " << *it << std::endl; 124 | } 125 | ctl::close_file( index_out); 126 | } 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /tools/euler_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2011 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | // Global Project Deps 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | //boost 14 | #include 15 | namespace po = boost::program_options; 16 | 17 | // Complex type 18 | typedef ctl::Abstract_simplex Simplex; 19 | typedef ctl::Finite_field< 2> Z2; 20 | typedef ctl::Simplex_boundary Simplex_boundary; 21 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 22 | typedef Complex::iterator Complex_iterator; 23 | typedef ctl::Timer Timer; 24 | 25 | 26 | template 27 | void process_args( int & argc, char *argv[],Variable_map & vm){ 28 | //parse command line options 29 | po::options_description desc( "Usage: tp [options] input-file"); 30 | desc.add_options() 31 | ( "help", "Display this message") 32 | ( "input-file", "input .asc file to parse"); 33 | po::positional_options_description p; 34 | p.add( "input-file",1); 35 | po::store( po::command_line_parser( argc,argv) 36 | .options( desc) 37 | .positional( p) 38 | .run(), 39 | vm); 40 | po::notify( vm); 41 | if ( vm.count( "help")){ 42 | std::cout << desc << std::endl; 43 | std::exit( 0); 44 | } 45 | if ( vm.count( "input-file") != 1){ 46 | std::cout << desc << std::endl; 47 | std::exit( -1); 48 | } 49 | } 50 | 51 | int main( int argc, char *argv[]){ 52 | po::variables_map vm; 53 | process_args( argc, argv, vm); 54 | //setup some variables 55 | std::string full_complex_name = vm[ "input-file"].as< std::string>(); 56 | std::string complex_name( full_complex_name); 57 | std::string binary_name( argv[ 0]); 58 | 59 | size_t found = complex_name.rfind( '/'); 60 | if ( found != std::string::npos){ 61 | complex_name.replace( 0, found+1, ""); 62 | } 63 | 64 | Complex complex; 65 | Timer timer; 66 | // Read the cell_set in 67 | //ctl::read_complex( full_complex_name, complex); 68 | int euler=0; 69 | timer.start(); 70 | for(auto cell : complex){ euler += 2*(cell.first.dimension()%2)-1; } 71 | timer.elapsed(); 72 | std::cout << "Euler characteristic: " << euler << " : " 73 | << timer.elapsed() << " secs" << std::endl; 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /tools/gpcover_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2011 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | //CTL 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | //BOOST 20 | #include 21 | 22 | //STL 23 | #include 24 | 25 | //TBB 26 | #include 27 | 28 | 29 | namespace po = boost::program_options; 30 | 31 | // Complex type 32 | typedef ctl::Abstract_simplex Cell; 33 | typedef ctl::Finite_field< 2> Z2; 34 | typedef ctl::Simplex_boundary Simplex_boundary; 35 | typedef ctl::Cell_complex< Simplex_boundary, 36 | ctl::parallel::Nerve_data> Nerve; 37 | typedef Nerve::iterator Nerve_iterator; 38 | typedef ctl::parallel::Cover_data< Nerve_iterator > Cover_data; 39 | typedef ctl::Cell_complex< Simplex_boundary, Cover_data> Complex; 40 | typedef Complex::iterator Complex_iterator; 41 | typedef ctl::Cell_less Cell_less; 42 | typedef ctl::Graded_cell_complex< Complex, Cell_less> Filtration; 43 | 44 | typedef ctl::Timer Timer; 45 | typedef ctl::parallel::Cover_stats< Timer> Stats; 46 | 47 | template 48 | void process_args( int & argc, char *argv[],Variable_map & vm){ 49 | //parse command line options 50 | po::options_description desc( "Usage: tp [options] input-file num-parts"); 51 | desc.add_options() 52 | ( "help", "Display this message") 53 | ( "input-file", "input .asc file to parse") 54 | ( "num-parts", "specify partition size"); 55 | po::positional_options_description p; 56 | p.add( "input-file",1); 57 | p.add( "num-parts",1); 58 | po::store( po::command_line_parser( argc,argv) 59 | .options( desc) 60 | .positional( p) 61 | .run(), 62 | vm); 63 | po::notify( vm); 64 | if ( vm.count( "help")){ 65 | std::cout << desc << std::endl; 66 | std::exit( 0); 67 | } 68 | if ( vm.count( "input-file") != 1 || vm.count( "num-parts") != 1){ 69 | std::cout << desc << std::endl; 70 | std::exit( -1); 71 | } 72 | } 73 | 74 | int main( int argc, char *argv[]){ 75 | po::variables_map vm; 76 | process_args( argc, argv, vm); 77 | size_t num_parts = atoi( vm[ "num-parts"].as< std::string>().c_str()); 78 | //setup some variables 79 | std::string full_complex_name = vm[ "input-file"].as< std::string>(); 80 | std::string complex_name( full_complex_name); 81 | std::string binary_name( argv[ 0]); 82 | 83 | size_t found = complex_name.rfind( '/'); 84 | if ( found != std::string::npos){ 85 | complex_name.replace( 0, found+1, ""); 86 | } 87 | tbb::task_scheduler_init init; 88 | 89 | Complex complex; 90 | Nerve nerve; 91 | 92 | // Read the cell_set in 93 | //read_complex( full_complex_name, complex); 94 | if (!complex.is_closed()){ 95 | std::cout << "complex is not closed" << std::endl; 96 | } 97 | Filtration filtration( complex); 98 | Stats stats; 99 | Timer timer; 100 | timer.start(); 101 | ctl::parallel::init_cover_complex( nerve, num_parts); 102 | ctl::parallel::graph_partition_cover( filtration, nerve); 103 | timer.elapsed(); 104 | double cover_time = timer.elapsed(); 105 | std::cout << "cover compute time: " << cover_time << std::endl; 106 | std::string cover_name ( full_complex_name); 107 | std::string nerve_name ( full_complex_name); 108 | 109 | found = cover_name.rfind( '.'); 110 | if (found == std::string::npos){ 111 | cover_name.append(".cov"); 112 | }else{ 113 | cover_name.replace(found,cover_name.size()-1,".cov"); 114 | } 115 | 116 | found = nerve_name.rfind( '.'); 117 | if (found == std::string::npos){ 118 | nerve_name.append(".nrv"); 119 | }else{ 120 | nerve_name.replace(found,nerve_name.size()-1,".nrv"); 121 | } 122 | 123 | std::ofstream out; 124 | ctl::open_file( out, nerve_name.c_str()); 125 | //out << nerve; 126 | ctl::close_file( out); 127 | 128 | ctl::open_file( out, cover_name.c_str()); 129 | //typedef ctl::parallel::Get_cover< Complex::Data> Cover_functor; 130 | //complex.write( out, Cover_functor()); 131 | //ctl::close_file( out); 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /tools/graph_to_metis_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ****************************************************************************** 3 | * Copyright (C) Ryan H. Lewis 2011 4 | ****************************************************************************** 5 | * BSD-3 6 | *******************************************************************************/ 7 | // STL 8 | #include 9 | #include 10 | #include 11 | 12 | // Project 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | typedef ctl::Abstract_simplex Simplex; 21 | typedef ctl::Finite_field< 2> Z2; 22 | typedef ctl::Simplex_boundary Simplex_boundary; 23 | typedef ctl::Cell_complex Complex; 24 | typedef Complex::Cell Cell; 25 | 26 | typedef ctl::Nbhd_graph<> Graph; 27 | typedef boost::graph_traits< Graph>::edges_size_type edges_size_type; 28 | typedef boost::vertex_name_t bvtx_name_t; 29 | typedef boost::property_map< Graph, bvtx_name_t>::type name_map_t; 30 | typedef boost::property_traits::value_type vertex_name_t; 31 | 32 | 33 | int main(int argc, char *argv[]) 34 | { 35 | if( argc != 2) { 36 | std::cerr << "Usage: " << argv[ 0] << " graph" << std::endl; 37 | } 38 | // Set up complex 39 | Graph graph; 40 | 41 | // Read the complex in 42 | std::ifstream in; 43 | ctl::open_file( in, argv[ 1]); 44 | in >> graph; 45 | ctl::close_file( in); 46 | 47 | int num_vertices = boost::num_vertices(graph); 48 | edges_size_type num_edges = boost::num_edges(graph); 49 | 50 | std::vector< int> offsets(num_vertices+1); 51 | std::vector< int> neighbors(2*num_edges); 52 | std::vector< int> part(num_vertices); 53 | 54 | //int options[10]; 55 | //options[0] = 0; 56 | 57 | //TODO: hash_map? 58 | std::map< vertex_name_t, int> vertex_to_idx; 59 | std::map< int, vertex_name_t> idx_to_vertex; 60 | 61 | //extract graph 62 | ctl::graph_to_metis( graph, offsets, neighbors, vertex_to_idx, idx_to_vertex); 63 | std::ofstream out; 64 | std::string metis_name ( argv[ 1]); 65 | size_t found = metis_name.rfind( '.'); 66 | if (found == std::string::npos){ 67 | metis_name.append( ".met"); 68 | }else{ 69 | metis_name.replace( found, metis_name.size()-1,".met"); 70 | } 71 | ctl::open_file( out, metis_name.c_str()); 72 | ctl::write_metis( out, offsets, neighbors); 73 | ctl::close_file( out); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /tools/ngraph.cpp: -------------------------------------------------------------------------------- 1 | //STL 2 | #include 3 | #include 4 | 5 | //CTL 6 | //Utility 7 | #include 8 | #include 9 | 10 | 11 | //Types for Points 12 | //#include 13 | 14 | //Types for Graphs 15 | #include 16 | #include 17 | #include 18 | 19 | //Types for Building a Simplicial Chain Complex 20 | //Abstract Simplex 21 | #include 22 | #include 23 | #include 24 | 25 | //Chain Complex 26 | #include 27 | #include 28 | #include 29 | 30 | //Graph 31 | typedef typename ctl::Nbhd_graph<> Graph; 32 | 33 | //Simplex 34 | typedef ctl::Abstract_simplex Simplex; 35 | typedef ctl::Finite_field< 2> Z2; 36 | typedef ctl::Simplex_boundary Simplex_boundary; 37 | 38 | //Chain Complex 39 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 40 | 41 | 42 | // temporary solution until we build points.h 43 | typedef std::vector Point; 44 | typedef std::vector Points; 45 | 46 | int main (int argc, char* argv[]) { 47 | if( argc != 4){ 48 | std::cerr << "Usage: " 49 | << argv[ 0] 50 | << " filename.dat max_epsilon max_dimension" << std::endl; 51 | return 0; 52 | } 53 | ctl::Timer clock; 54 | double epsilon = atof( argv[ 2]); 55 | 56 | Points points; 57 | std::ifstream in; 58 | ctl::open_file( in, argv[ 1]); 59 | std::string output_file( argv[ 1]); 60 | auto pos = output_file.rfind('.'); 61 | if( pos != std::string::npos){ 62 | output_file.erase(output_file.begin()+pos, output_file.end()); 63 | } 64 | output_file.append(".ngh"); 65 | Point point; 66 | double coordinate; 67 | std::size_t line_num = 0; 68 | while( true){ 69 | std::string line; 70 | ctl::get_line( in, line, line_num); 71 | if( in.eof() ) break; 72 | std::stringstream ss( line); 73 | while( ss.good()){ 74 | ss >> coordinate; 75 | point.push_back( coordinate); 76 | } 77 | points.push_back( point); 78 | point.clear(); 79 | } 80 | clock.start(); 81 | Graph graph; 82 | ctl::epsilon_search::construct_graph(points, epsilon, graph); 83 | std::cerr << "Graph construction: " << clock.elapsed() << std::endl; 84 | std::cerr << "# vertices = " << boost::num_vertices( graph) << std::endl; 85 | std::cerr << "# edges = " << boost:: num_edges( graph) << std::endl; 86 | std::ofstream out( output_file.c_str()); 87 | out << graph; 88 | out.close(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /tools/phat_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2011 3 | ******************************************************************************* 4 | * BSD-3 5 | *******************************************************************************/ 6 | #define COMPUTE_BETTI 7 | //#define TESTS_ON 8 | 9 | // Global Project Deps 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | //BOOST 23 | #include 24 | 25 | //STL 26 | #include 27 | #include 28 | //TODO: tool should generically handle _any_ cell type 29 | //TODO: should have a weighted complex type like in the VR paper 30 | // Should be a mechanism for arbitrary filtrations. 31 | namespace po = boost::program_options; 32 | 33 | // Complex type 34 | typedef ctl::Abstract_simplex Cell; 35 | typedef ctl::Finite_field< 2> Z2; 36 | typedef ctl::Simplex_boundary Simplex_boundary; 37 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 38 | typedef Complex::iterator Complex_iterator; 39 | typedef ctl::Cell_less Cell_less; 40 | typedef ctl::Graded_cell_complex< Complex, Cell_less> Complex_filtration; 41 | typedef Complex_filtration::iterator Complex_filtration_iterator; 42 | 43 | 44 | template 45 | void process_args( int & argc, char *argv[],Variable_map & vm){ 46 | //parse command line options 47 | po::options_description desc( "Usage: write_filtration [options] input-file"); 48 | desc.add_options() 49 | ( "help", "Display this message") 50 | ( "input-file", "input .asc file to parse"); 51 | po::positional_options_description p; 52 | p.add( "input-file",1); 53 | po::store( po::command_line_parser( argc,argv) 54 | .options( desc) 55 | .positional( p) 56 | .run(), 57 | vm); 58 | po::notify( vm); 59 | if ( vm.count( "help")){ 60 | std::cout << desc << std::endl; 61 | std::exit( 0); 62 | } 63 | if ( vm.count( "input-file") != 1){ 64 | std::cout << desc << std::endl; 65 | std::exit( -1); 66 | } 67 | } 68 | 69 | int main( int argc, char *argv[]){ 70 | po::variables_map vm; 71 | process_args( argc, argv, vm); 72 | 73 | //setup some variables 74 | std::string full_complex_name = vm[ "input-file"].as< std::string>(); 75 | std::string complex_name( full_complex_name); 76 | std::string binary_name( argv[ 0]); 77 | std::string base_name( full_complex_name); 78 | std::string output_name; 79 | size_t found = complex_name.rfind( '/'); 80 | if ( found != std::string::npos){ 81 | complex_name.replace( 0, found+1, ""); 82 | } 83 | found = full_complex_name.rfind('.'); 84 | if ( found != std::string::npos){ 85 | base_name.replace(found,full_complex_name.length(), ""); 86 | output_name = base_name + ".phat"; 87 | } 88 | std::ofstream out(output_name.c_str()); 89 | 90 | Complex complex; 91 | 92 | // Read the cell_set in 93 | //ctl::read_complex( full_complex_name, complex); 94 | 95 | Complex_filtration complex_filtration( complex); 96 | 97 | 98 | typedef ctl::Graded_boundary< Complex_filtration> 99 | Filtration_boundary; 100 | typedef Filtration_boundary::Term Filtration_term; 101 | typedef ctl::Chain< Filtration_term> Chain; 102 | std::cout << "Writing PHAT ASCII file To: " << output_name << std::endl; 103 | Filtration_boundary bd( complex_filtration); 104 | for (Complex_filtration_iterator sigma = complex_filtration.begin(); 105 | sigma != complex_filtration.end(); ++sigma){ 106 | Chain cascade_boundary; 107 | cascade_boundary.reserve( bd.length( sigma)); 108 | for( auto i = bd.begin( sigma); i != bd.end( sigma); ++i){ 109 | cascade_boundary.emplace( i->cell(), i->coefficient()); 110 | } 111 | cascade_boundary.sort(); 112 | std::size_t dim = (*sigma)->first.dimension(); 113 | out << dim; 114 | for( auto term : cascade_boundary){ 115 | out << " " << term.cell(); 116 | } 117 | out << std::endl; 118 | } 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /tools/sphere.cpp: -------------------------------------------------------------------------------- 1 | //STL 2 | #include 3 | 4 | template< typename OutputIterator> 5 | void nsphere( std::size_t n, std::size_t k, 6 | double variance_of_noise, OutputIterator out){ 7 | 8 | std::default_random_engine generator; 9 | std::normal_distribution distribution(0.0,1.0); 10 | distribution(generator) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tools/vr.cpp: -------------------------------------------------------------------------------- 1 | //STL 2 | #include 3 | #include 4 | 5 | //CTL 6 | //Utility 7 | #include 8 | #include 9 | 10 | 11 | //Types for Points 12 | //#include 13 | 14 | //Types for Graphs 15 | #include 16 | 17 | //Types for Building a Simplicial Chain Complex 18 | //Abstract Simplex 19 | #include 20 | #include 21 | #include 22 | 23 | //Chain Complex 24 | #include 25 | #include 26 | #include 27 | 28 | //VR Construction 29 | #include 30 | #include 31 | #include 32 | 33 | //Graph 34 | 35 | template< typename Points> 36 | decltype(auto) compute_vr_complex(Points points, double epsilon, std::size_t dimension){ 37 | //Simplex 38 | typedef typename ctl::Nbhd_graph<> Graph; 39 | //typedef ctl::Abstract_simplex Simplex; 40 | //typedef ctl::Finite_field< 2> Z2; 41 | typedef ctl::Simplex_boundary Simplex_boundary; 42 | 43 | //Chain Complex 44 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 45 | Graph graph; 46 | Complex complex; 47 | ctl::epsilon_search::construct_graph(points, epsilon, graph); 48 | ctl::incremental_vr( graph, complex, dimension); 49 | return complex; 50 | } 51 | 52 | 53 | // temporary solution until we build points.h 54 | typedef std::vector Point; 55 | typedef std::vector Points; 56 | 57 | int main (int argc, char* argv[]) { 58 | if( argc != 4){ 59 | std::cerr << "Usage: " 60 | << argv[ 0] 61 | << " filename.dat max_epsilon max_dimension" << std::endl; 62 | return 0; 63 | } 64 | ctl::Timer clock; 65 | double epsilon = atof( argv[ 2]); 66 | std::size_t dimension = atoi( argv[ 3]); 67 | 68 | Points points; 69 | std::ifstream in; 70 | ctl::open_file( in, argv[ 1]); 71 | std::string output_file( argv[ 1]); 72 | auto pos = output_file.rfind('.'); 73 | if( pos != std::string::npos){ 74 | output_file.erase(output_file.begin()+pos, output_file.end()); 75 | } 76 | output_file.append(".asc"); 77 | Point point; 78 | double coordinate; 79 | std::size_t line_num = 0; 80 | while( true){ 81 | std::string line; 82 | ctl::get_line( in, line, line_num); 83 | if( in.eof() ) break; 84 | std::stringstream ss( line); 85 | while( ss.good()){ 86 | ss >> coordinate; 87 | point.push_back( coordinate); 88 | } 89 | points.push_back( point); 90 | point.clear(); 91 | } 92 | clock.start(); 93 | ctl::Nbhd_graph<> graph; 94 | ctl::Simplicial_complex<> complex; 95 | ctl::epsilon_search::construct_graph(points, epsilon, graph); 96 | ctl::incremental_vr( graph, complex, dimension); 97 | std::cerr << "Complex construction: " << clock.elapsed() << std::endl; 98 | std::ofstream out( output_file.c_str()); 99 | std::cerr << "|K| = " << complex.size() << std::endl; 100 | std::cout << "Writing to disk ... " << std::flush; 101 | //complex.write( out); 102 | std::cout << " complete!" << std::endl; 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /tools/witness.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appliedtopology/ctl/b610fa4a9afc439b071457dd0c9d1a823ac1537a/tools/witness.cpp -------------------------------------------------------------------------------- /tools/write_filtration_tool.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (C) Ryan H. Lewis 2011 3 | ****************************************************************************** 4 | * BSD-3 5 | *******************************************************************************/ 6 | #define COMPUTE_BETTI 7 | //#define TESTS_ON 8 | 9 | // Global Project Deps 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | //BOOST 20 | #include 21 | 22 | //STL 23 | #include 24 | #include 25 | //TODO: tool should generically handle _any_ cell type 26 | //TODO: should have a weighted complex type like in the VR paper 27 | // Should be a mechanism for arbitrary filtrations. 28 | namespace po = boost::program_options; 29 | 30 | // Complex type 31 | typedef ctl::Abstract_simplex Cell; 32 | typedef ctl::Finite_field< 2> Z2; 33 | typedef ctl::Simplex_boundary Simplex_boundary; 34 | typedef ctl::Cell_complex< Simplex_boundary> Complex; 35 | typedef Complex::iterator Complex_iterator; 36 | typedef ctl::Cell_less Cell_less; 37 | typedef ctl::Graded_cell_complex< Complex, Cell_less> Complex_filtration; 38 | typedef Complex_filtration::iterator Complex_filtration_iterator; 39 | 40 | 41 | template 42 | void process_args( int & argc, char *argv[],Variable_map & vm){ 43 | //parse command line options 44 | po::options_description desc( "Usage: write_filtration [options] input-file"); 45 | desc.add_options() 46 | ( "help", "Display this message") 47 | ( "input-file", "input .asc file to parse"); 48 | po::positional_options_description p; 49 | p.add( "input-file",1); 50 | po::store( po::command_line_parser( argc,argv) 51 | .options( desc) 52 | .positional( p) 53 | .run(), 54 | vm); 55 | po::notify( vm); 56 | if ( vm.count( "help")){ 57 | std::cout << desc << std::endl; 58 | std::exit( 0); 59 | } 60 | if ( vm.count( "input-file") != 1){ 61 | std::cout << desc << std::endl; 62 | std::exit( -1); 63 | } 64 | } 65 | 66 | int main( int argc, char *argv[]){ 67 | po::variables_map vm; 68 | process_args( argc, argv, vm); 69 | 70 | //setup some variables 71 | std::string full_complex_name = vm[ "input-file"].as< std::string>(); 72 | std::string complex_name( full_complex_name); 73 | std::string binary_name( argv[ 0]); 74 | std::string base_name( full_complex_name); 75 | std::string output_name; 76 | size_t found = complex_name.rfind( '/'); 77 | if ( found != std::string::npos){ 78 | complex_name.replace( 0, found+1, ""); 79 | } 80 | found = full_complex_name.rfind('.'); 81 | if ( found != std::string::npos){ 82 | base_name.replace(found,full_complex_name.length(), ""); 83 | output_name = base_name + ".flt"; 84 | } 85 | 86 | Complex complex; 87 | 88 | // Read the cell_set in 89 | //ctl::read_complex( full_complex_name, complex); 90 | 91 | Complex_filtration complex_filtration( complex); 92 | std::cout << "Writing Filtration To: " << output_name << std::endl; 93 | std::ofstream out(output_name.c_str()); 94 | std::size_t count = 0; 95 | for (Complex_filtration_iterator i = complex_filtration.begin(); i != complex_filtration.end(); ++i){ 96 | out << (*i)->second.id() << " " << ++count << std::endl; 97 | } 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /travis/ci_fedora.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #we do not support clang on ubuntu 12.x.. 3 | 4 | sudo yum install tbb-devel metis-devel boost-devel 5 | mkdir build && cd build 6 | cmake .. 7 | make -j4 8 | make run_tests 9 | -------------------------------------------------------------------------------- /travis/ci_osx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #CC=clang 3 | #CXX=clang++ 4 | brew tap homebrew/science 5 | brew install tbb metis ann 6 | #brew install boost ---build-from-source --with-c++11 --with-mpi --with-program_options --with-clang --without-single 7 | -------------------------------------------------------------------------------- /travis/ci_ubuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #we do not support clang on ubuntu 12.x.. 3 | CC=gcc 4 | CXX=g++ 5 | #These are all hacks to get stuff not available on Ubuntu 12.xx 6 | sudo add-apt-repository ppa:libreoffice/ppa -y 7 | sudo add-apt-repository ppa:yade-users/external -y 8 | #sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y 9 | sudo apt-get clean 10 | sudo apt-get update -qq 11 | sudo apt-get install libann-dev libboost1.54-all-dev libtbb-dev libmetis-dev 12 | --------------------------------------------------------------------------------