main.rs

3.1 kB · rust · 89 lines

1mod graphs;2mod multiplicity;3mod numerics;4mod spectrum;5mod unfolding;67use graphs::Graph;8use numerics::{fraction_below, goe, ks_distance, ks_pvalue, poisson};910const DEGREE: usize = 12;11const HALF: usize = 10;12const TOLERANCE: f64 = 1e-9;1314struct Row {15    name: String,16    graph: Graph,17}1819fn subjects() -> Vec<Row> {20    let mut out = Vec::new();21    let mut push = |name: String, graph: Graph| out.push(Row { name, graph });22    push(23        "random graph n=400 p=0.1".into(),24        graphs::random(400, 0.1, 7),25    );26    push("square lattice 20x20".into(), graphs::square(20));27    push("carpet L=3".into(), graphs::carpet(3));28    push("carpet L=4".into(), graphs::carpet(4));29    push("sponge L=2".into(), graphs::sponge(2));30    push("slice L=2".into(), graphs::slice(2));31    push("slice L=3".into(), graphs::slice(3));32    push("sierpinski L=5".into(), graphs::sierpinski(5));33    push("sierpinski L=6".into(), graphs::sierpinski(6));34    out35}3637fn report(label: &str, spacings: &unfolding::Spacings) {38    let m = spacings.values.len();39    let d_goe = ks_distance(&spacings.values, goe);40    let d_poi = ks_distance(&spacings.values, poisson);41    println!(42        "    {label}: P(s<0.5) = {:.4}  KS goe = {:.4} (p = {:.3})  KS poisson = {:.4} (p = {:.3})  negative steps = {}",43        fraction_below(&spacings.values, 0.5),44        d_goe,45        ks_pvalue(d_goe, m),46        d_poi,47        ks_pvalue(d_poi, m),48        spacings.negatives49    );50}5152fn main() {53    println!("GOE P(s<0.5) = 1 - exp(-pi/16) = {:.5}", goe(0.5));54    println!("POISSON P(s<0.5) = 1 - exp(-1/2) = {:.5}", poisson(0.5));55    println!("polynomial unfolder degree {DEGREE}, window unfolder half width {HALF}, clustering tolerance {TOLERANCE:e}");56    for row in subjects() {57        let graph = &row.graph;58        println!(59            "{}: {} nodes, {} edges, {} components",60            row.name,61            graph.nodes(),62            graph.edges(),63            graph.components()64        );65        for (kind, normalised) in [("combinatorial", false), ("normalised", true)] {66            let values = spectrum::eigenvalues(graph, normalised);67            let classes = multiplicity::classes(&values, TOLERANCE);68            println!(69                "  {kind} laplacian: distinct {} ({:.2}%), zero spacings {} ({:.2}%), in repeated classes {} ({:.2}%), largest multiplicity {}",70                classes.distinct,71                100.0 * classes.distinct as f64 / values.len() as f64,72                values.len() - classes.distinct,73                100.0 * (values.len() - classes.distinct) as f64 / values.len() as f64,74                classes.repeated,75                100.0 * classes.repeated as f64 / values.len() as f64,76                classes.largest77            );78            report("polynomial", &unfolding::polynomial(&values, DEGREE));79            report("window", &unfolding::window(&values, HALF));80        }81    }82    let big = graphs::slice(4);83    println!(84        "slice L=4: {} nodes, {} edges, {} components, spectrum not computed",85        big.nodes(),86        big.edges(),87        big.components()88    );89}