#拓扑 #组合数学 #随机 #单纯 #betti

bin+lib simplicial_topology

表示、操作、组合单纯复形并执行计算

3个版本

0.1.2 2023年7月18日
0.1.1 2023年5月15日
0.1.0 2023年5月15日

#598 in 数学

每月 30 次下载

MIT 许可证

45KB
833

单纯拓扑

一个用于处理单纯复形的Rust库。

概述

此库为在Rust中构建和操作单纯复形提供工具。主要数据类型是SimplicialComplex,它将单纯复形表示为各种维度的面的集合。这种表示方式是单纯复形最内存高效的表示方式。

此库可以轻松生成多种不同模型的随机单纯复形。

功能

  • 单纯形表示为一个具有额外结构(边界等)的向量。
  • 从单纯形的向量(或向量的向量)构建单纯复形。
  • 计算边界矩阵和betti数
  • 生成随机单纯复形。当前包含以下模型:Linial-MeshulamLowerUpperPure

用法

基本设置

要在您的Rust项目中使用simplicial-topology,请将以下内容添加到您的Cargo.toml

[dependencies]
simplicial_topology = {version = "0.1.1", features = ["sc_plot"]}
# sc_plot is an optional feature for being able to plot histograms for random complex Betti numbers

基本用法

use simplicial_topology::{sc, simplicial_complex::SimplicialComplex};

let sc = SimplicialComplex::new_from_vec(vec![vec![0, 1], vec![1, 2], vec![1, 2, 3], vec![3, 4], vec![1, 3, 4]]);
let _sc = sc![vec![0, 1], vec![1, 2], vec![1, 2, 3], vec![3, 4], vec![1, 3, 4]]; // Note this is the shorthand macro to construct an identical SimplicialComplex to sc
assert_eq!(sc, _sc);

println!("The complex has {} facets", sc.facets.len()); // This will output "The complex has 3 facets"
println!("The complex has dimension {}", sc.dimension()); // This will output "The complex has dimension 2"

betti数

use simplicial_topology::sc;

let mut sc = sc![vec![1,2], vec![2,3], vec![1,3], vec![1,4], vec![4,5], vec![1,5]]; // This is the wedge of two simplicial circles (bdy of [1,2,3] and bdy of [1,4,5])
sc.add_simplex(simplex![1,4,5]); // Here we add in the simplex [1,4,5] filling in a circle. If the boundary of this simplex didn't exist then add_simplex would panic
println!("Betti vector: {:?}", sc.betti_numbers()); // This will output "Betti vector: [1, 1, 0]"
println!("Euler characteristic: {}", sc.euler_characteristic()); // This will output "Euler characteristc: 0

注意,我们可以构建上面的原始sc稍微整洁一些

use simplicial_topology::{simplex, simplicial_complex::SimplicialComplex};

let sigma: Facet = simplex![1,2,3];
let tau: Facet = simplex![1,4,5];
let sc: SimplicialComplex = sigma.boundary_as_complex().union(&tau.boundary_as_complex()); // boundary_as_complex() returns the boundary of the simplex but as a SimplicialComplex, rather than Vec<Facet>

上面的方法特别有助于我们与大型单纯球体交互。

随机复形

use simplicial_topology::simplicial_complex::random_simplicial_complex::{generate_random_simplicial_complex, Model};

let model = Model::LinialMeshulam {num_vertices: 20, dimension: 4, prob: 0.314159265};
let sc = generate_random_simplicial_complex(model);

assert_eq!(sc.contains_full_k_skeleton(3), true); // This is by definition true for this Linial-Meshulam random complex

所有可用的模型类型都来自构建一个随机超图(从给定顶点集的随机向量集合)并应用向上或向下闭包。

pub enum Model {
    Lower {num_vertices: usize, prob_vec: Vec<f64>},
    Upper {num_vertices: usize, prob_vec: Vec<f64>},
    LinialMeshulam {num_vertices: usize, dimension: usize, prob: f64},
    Pure {num_vertices: usize, dimension: usize, prob: f64, include_all_vertices: bool}
}

我们可以生成并绘制随机单纯复形的betti数的分布。以下代码返回一个交互式plotly直方图。必须将sc_plot功能添加到Cargo.toml中才能实现此功能。

use simplicial_topology::simplicial_complex::random_simplicial_complex::{generate_many_random_betti_numbers, Model};
use simplicial_topology::graphics::plot::betti_number_histogram;

let n: usize = 20;
let prob_vec: Vec<f64> = vec![1.0, 1.0/(n as f64).powf(0.5), 1.0];
let model = Model::Lower {num_vertices: n, prob_vec: prob_vec };

let betti_numbers: Vec<Vec<i32>> = generate_many_random_betti_numbers(1000, model);
println!("{:?}", betti_numbers);
let plot = betti_number_histogram(&betti_numbers);

其他操作

以下给出了一组其他操作的简单示例,可以将它们连接起来形成新的复形,或获取现有复形的属性。

use simplicial_topology::{sc, simplex, simplicial_complex::SimplicialComplex};

let sc1 = sc![vec![1,2,3]];
let sc2 = simplex![2,3,4].boundary_as_complex();
sc1.dimension(); // 2
sc2.dimension(); // 1
sc1.intersection(&sc2); // sc![vec![2,3]]);
sc1.union(&sc2); // sc![vec![1,2,3], vec![3,4], vec![2,4]]
sc1.link(&simplex![2]); // sc![vec![1,3]]
sc2.star(&simplex![2]); // sc![vec![2,3], vec![2,4]]
sc2.add_simplex(simplex![2,3,4]); // sc![vec![2,3,4]], will change sc2 in place
sc1.add_simplex(simplex![2,3,4]); // panics as the boundary of this simplex is not in sc1
sc1.k_skeleton(1); // sc![vec![1,2], vec![1,3], vec![2,3]]
sc2.kth_betti_number(1);; // 1
sc1.is_connected(); // True
sc![vec![1,2,3], vec![4]].is_connected(); // False
sc![vec![1,2,3], vec![4]].alexander_dual(); // sc![vec![1,2], vec![1,3], vec![2,3]] - the dual complex X* on [n] where \sigma is a face iff [n] - \sigma is not a face in X

限制

与许多单纯复形库的标准做法一样,同调(或者更确切地说,betti数)是在 $\mathbb{Z}/2\mathbb{Z}$ 上计算的。这是为了跟踪方向而采取的一种规避方法。

目前,同伦群的基础并没有被跟踪,例如,我们知道复形 sc![vec![1,2], vec![1,3], vec![2,3]] 的第一个贝蒂数等于 1,但不知道这个周期是由 <[1,2], [1,3], [2,3]> 生成的。

访问复形的 $k$ 维面比其他库慢。这是因为只存储了面,因此如果我们需要其他面,它们需要即时计算。

依赖关系

~11–24MB
~332K SLoC