3个版本
0.1.2 | 2023年7月18日 |
---|---|
0.1.1 | 2023年5月15日 |
0.1.0 | 2023年5月15日 |
#598 in 数学
每月 30 次下载
45KB
833 行
单纯拓扑
一个用于处理单纯复形的Rust库。
概述
此库为在Rust中构建和操作单纯复形提供工具。主要数据类型是SimplicialComplex
,它将单纯复形表示为各种维度的面的集合。这种表示方式是单纯复形最内存高效的表示方式。
此库可以轻松生成多种不同模型的随机单纯复形。
功能
- 单纯形表示为一个具有额外结构(边界等)的向量。
- 从单纯形的向量(或向量的向量)构建单纯复形。
- 计算边界矩阵和betti数
- 生成随机单纯复形。当前包含以下模型:Linial-Meshulam、Lower、Upper 和 Pure。
用法
基本设置
要在您的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