Skip to content
Merged

Dev #22

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: ["ubuntu-latest"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: ["macos-latest"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
fail-fast: false
matrix:
os: ["windows-latest"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
matrix:
os: [windows-latest]
cibw_arch: ["AMD64"]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*"]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*"]

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -77,7 +77,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*"]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*"]
cibw_arch: ["x86_64", "arm64"] # TODO: add "universal2" once a universal2 libomp is available

steps:
Expand Down Expand Up @@ -159,7 +159,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*"]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*"]
cibw_manylinux: [manylinux2014]
cibw_arch: ["x86_64"]

Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ This project loosely adheres to [semantic versioning](https://semver.org/spec/v2
## Unreleased [v0.1.2]

- Exported underlying `st.reindex()` function to allow node relabeling

- Added ability to chaneg the default simplex output type via the `s_type` Callable
- Re-added vertex/edge contraction to the API

## [v0.1.1](https://github.com/peekxc/simplextree-py/releases/tag/v0.1.1) - 2023-08-20

Expand Down
7 changes: 4 additions & 3 deletions include/simplextree.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ struct SimplexTree {
struct less_ptr {
bool operator() (const node_uptr& lhs, const node_uptr& rhs) const { return (*lhs) < (*rhs); }
};
using node_set_t = set< node_uptr, less_ptr >;
// using node_set_t = set< node_uptr, less_ptr >;
using node_set_t = vector< node_uptr >;
using simplex_t = vector< idx_t >;
using cousin_map_t = std::map< idx_t, vector< node_ptr > >;
using difference_type = std::ptrdiff_t;
Expand Down Expand Up @@ -217,15 +218,15 @@ struct SimplexTree {
auto collapse(node_ptr, node_ptr) -> bool;
auto vertex_collapse(idx_t, idx_t, idx_t) -> bool;
auto vertex_collapse(node_ptr, node_ptr, node_ptr) -> bool;
auto contract(simplex_t) -> void;
auto contract(simplex_t) -> bool;

auto expansion(const idx_t k) -> void;

template < typename Lambda >
auto expansion_f(const idx_t, Lambda&&) -> void;

template < typename Lambda >
auto expand_f(node_set_t&, const idx_t, size_t, Lambda&&) -> void;
auto expand_f(node_set_t&, const idx_t, size_t, Lambda&&, SmallVector< node_ptr >&, SmallVector< node_ptr >&) -> void;

template < typename Lambda >
void traverse_up(node_ptr, const size_t, Lambda&&) const noexcept;
Expand Down
67 changes: 47 additions & 20 deletions include/simplextree/st.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ inline void SimplexTree::remove(node_ptr cn){

template< typename Iter >
inline auto SimplexTree::append_node(Iter pos, node_ptr cn, idx_t label, size_t depth) -> node_set_t::iterator {
auto new_it = cn->children.emplace_hint(pos, make_unique< node >(label, cn));
// auto new_it = cn->children.emplace_hint(pos, make_unique< node >(label, cn)); // set
auto new_it = cn->children.emplace(pos, make_unique< node >(label, cn)); // vector
add_cousin((*new_it).get(), depth);
record_new_simplexes(depth-1, 1);
return(new_it);
Expand Down Expand Up @@ -264,13 +265,22 @@ inline void SimplexTree::insert_it(Iter s, Iter e, node_ptr c_node, const idx_t
// }
// record_new_simplexes(child_depth-1, 1);
// } else {
auto it = std::find_if(begin(node_children(c_node)), end(node_children(c_node)), [label](const node_uptr& cn){
return(cn->label == label);
// original
// auto it = std::find_if(begin(node_children(c_node)), end(node_children(c_node)), [label](const node_uptr& cn){
// return(cn->label == label);
// });
auto it = std::lower_bound(begin(node_children(c_node)), end(node_children(c_node)), label, [](const node_uptr& cn, idx_t c_label){
return cn->label < c_label;
});
if (it == end(c_node->children)){
auto new_it = c_node->children.emplace_hint(it, make_unique< node >(label, c_node));
if (it == end(c_node->children) || (*it)->label != label){
// auto new_it = c_node->children.emplace_hint(it, make_unique< node >(label, c_node)); // set
// auto& new_it = c_node->children.emplace_back(make_unique< node >(label, c_node)); // vector
auto new_it = c_node->children.emplace(it, make_unique< node >(label, c_node)); // vector

if (child_depth > 1){ // keep track of nodes which share ids at the same depth
add_cousin((*new_it).get(), child_depth);
// add_cousin((*new_it).get(), child_depth); // set
// add_cousin(new_it.get(), child_depth); // vector
add_cousin((*new_it).get(), child_depth); // vector emplace
}
record_new_simplexes(child_depth-1, 1);
}
Expand Down Expand Up @@ -439,38 +449,51 @@ inline void SimplexTree::print_simplex(OutputStream& os, node_ptr cn, bool newli

// Performs the default expansion of order k, reconstructing the k-skeleton flag complex via an in-depth expansion of the 1-skeleton.
inline void SimplexTree::expansion(const idx_t k){
expansion_f(k, [this](node_ptr parent, idx_t depth, idx_t label){
std::array< idx_t, 1 > int_label = { label };
std::array< idx_t, 1 > int_label = { 0 };
expansion_f(k, [this, &int_label](node_ptr parent, idx_t depth, idx_t label){
// std::array< idx_t, 1 > int_label = { label };
int_label[0] = label;
insert_it(begin(int_label), end(int_label), parent, depth);
});
}

// Global expansion operation: calls expand_f on all children of the root node
template < typename Lambda >
inline void SimplexTree::expansion_f(const idx_t k, Lambda&& f){
SmallVector< node_ptr >::allocator_type::arena_type arena1;
SmallVector< node_ptr > intersection { arena1 };
SmallVector< node_ptr >::allocator_type::arena_type arena2;
SmallVector< node_ptr > sib_ptrs { arena2 } ;
for (auto& cn: node_children(root)){
if (!node_children(cn).empty()){
expand_f(cn->children, k-1, 2, f);
expand_f(cn->children, k-1, 2, f, intersection, sib_ptrs);
}
}
}

// Local expand operation checks A \cap N^+(vj) \neq \emptyset
// If they have a non-empty intersection, then the intersection is added as a child to the head node and expand is recursivey called.
template < typename Lambda >
inline void SimplexTree::expand_f(node_set_t& c_set, const idx_t k, size_t depth, Lambda&& f){
inline void SimplexTree::expand_f(
node_set_t& c_set, const idx_t k, size_t depth,
Lambda&& f,
SmallVector< node_ptr >& intersection,
SmallVector< node_ptr >& sib_ptrs
){
if (k == 0 || c_set.empty()){ return; }
// Traverse the children
auto siblings = std::next(begin(c_set), 1);
SmallVector< node_ptr >::allocator_type::arena_type arena1;
SmallVector< node_ptr > intersection { arena1 };
// SmallVector< node_ptr >::allocator_type::arena_type arena1;
// SmallVector< node_ptr > intersection { arena1 };
intersection.clear();
for (auto& cn: c_set){
node_ptr top_v = find_by_id(root->children, cn->label);
if (top_v != nullptr && (!top_v->children.empty())){

// Temporary
SmallVector< node_ptr >::allocator_type::arena_type arena2;
SmallVector< node_ptr > sib_ptrs { arena2 } ;
// SmallVector< node_ptr >::allocator_type::arena_type arena2;
// SmallVector< node_ptr > sib_ptrs { arena2 } ;
sib_ptrs.clear();
std::transform(siblings, end(c_set), std::back_inserter(sib_ptrs), [](const node_uptr& n){
return (node_ptr) n.get();
});
Expand All @@ -492,7 +515,7 @@ inline void SimplexTree::expand_f(node_set_t& c_set, const idx_t k, size_t depth
f((node_ptr) cn.get(), depth, int_node->label);
}
}
expand_f(cn->children, k-1, depth+1, f); // recurse
expand_f(cn->children, k-1, depth+1, f, intersection, sib_ptrs); // recurse
}
}
if (siblings != end(c_set)){ ++siblings; }
Expand Down Expand Up @@ -684,7 +707,8 @@ inline vector< idx_t > SimplexTree::connected_components() const{
}

// Edge contraction
inline void SimplexTree::contract(vector< idx_t > edge){
inline bool SimplexTree::contract(vector< idx_t > edge){
if (edge.size() != 2){ return false; }
vector< simplex_t > to_remove;
vector< simplex_t > to_insert;
traverse(st::preorder< true >(this, root.get()), [this, edge, &to_remove, &to_insert](node_ptr np, idx_t depth, simplex_t sigma){
Expand All @@ -707,11 +731,14 @@ inline void SimplexTree::contract(vector< idx_t > edge){
return true;
});

// for (auto& edge: to_remove){ print_simplex(std::cout, edge, true); }

// Remove the simplices containing vb
for (auto& edge: to_remove){ remove(find(edge)); }
for (auto& edge: to_insert){ insert(edge); }
if (to_remove.size() > 0 || to_insert.size() > 0){
for (auto& edge: to_remove){ remove(find(edge)); }
for (auto& edge: to_insert){ insert(edge); }
return true;
} else {
return false;
}
}

template < typename Lambda > // Assume lambda is boolean return
Expand Down
33 changes: 31 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ project(
license: 'Apache-2.0',
meson_version: '>= 0.64.0',
default_options : [
'buildtype=debugoptimized',
'buildtype=release',
'b_ndebug=if-release',
'cpp_std=c++17',
'warning_level=2'
'warning_level=2',
'pkgconfig.relocatable=true'
]
)

Expand All @@ -26,6 +28,33 @@ inc_local = include_directories('include')
incdir_numpy = run_command(py, ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], check : true).stdout().strip()
inc_np = include_directories(incdir_numpy)

## Begin compiler arguments
compiler = meson.get_compiler('cpp')
message('Compiler = '+compiler.get_id())
_cpp_args = []
if get_option('buildtype') == 'debugoptimized'
_cpp_args += compiler.get_supported_arguments(
'-O2',
# '-fsanitize=address',
# '-fno-omit-frame-pointer',
'-g',
'-Wall'
)
else
## Release
_cpp_args += compiler.get_supported_arguments(
'-flto=thin', # think LTO
# '-flto', # monolithic LTO
'-O3', # full optimizations
'-DNDEBUG', # remove assertions
'-Wl,-s', # strip symbols to reduce binary size
# '-march=native' # either this or lto seems to not work on multiple builds
)
endif




## Compile the package directory
subdir('simplextree')

Expand Down
Loading