~mht/cra

ref: 933b27350404d77d37a8f2b73e9ae8bc2139e4a5 cra/cra/src/log.rs -rw-r--r-- 6.2 KiB
933b2735 — Martin Hafskjold Thoresen Fix warnings and remove some dead code 1 year, 5 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//! This module contains a log of all actions that happens during the run of the algorithms.
//! It is meant to be used by constructing an `Entry`, and operate on it during the course of the algorithm.

use std::collections::HashMap;

use crate::serde::Serialize;

use crate::persistence::Simplex;

/// Stats for a single `simplex_reduce` call.
#[derive(Debug, Copy, Clone)]
pub struct Add {
    /// The dimension of the simplices added together
    pub dim: isize,
    /// The size of the boundary of the simplex that is being reduced.
    pub this_size: usize,
    /// The size of the boundary of the other simplex.
    pub other_size: usize,
    /// This is true when this add was an exhaustive add, namely that low(this) \notin other.
    pub exhaustive: bool,
    /// The ID of the reduced simplex
   	this_j: usize,
   	/// The ID of the other simplex
   	other_j: usize,
}

/// Stats for reducting one simplex.
#[derive(Debug)]
pub struct SimplexReduction {
    /// All adds before the simplex was reduced
    pub adds: Vec<Add>,
    /// This simplex's lowest boundary element after reduced, if any.
    pub place_index: Option<usize>,
    /// Dimension of the simplex
    pub dim: isize,
}

/// Stats for a whole run of the reduction algorithm.
#[derive(Debug)]
pub struct Reduction {
	pub reductions: Vec<SimplexReduction>
}

/// This is the full data that we output.
#[derive(Debug)]
#[derive(Serialize)]
pub struct Aggregate {
    /// Simplex IDs of all additions.
    adds: Vec<(usize, usize)>,
    /// The average number of additions required to reduce a simplex, by dimension.
    avg_adds_required: HashMap<isize, f64>,

	/// The size of a simplex when we add them to reduce the first.
    add_size_by_dim: HashMap<isize, Vec<(usize, usize)>>,
    /// Average of the sizes.
    avg_add_size_by_dim: HashMap<isize, (f64, f64)>,
    /// Histogram of the sizes
    histogram_add_size_by_dim: HashMap<isize, HashMap<usize, (usize, usize)>>,

	/// The sum of sizes of simplices when we reduce
    add_cost_by_dim: HashMap<isize, Vec<usize>>,
    avg_add_cost_by_dim: HashMap<isize, f64>,
    histogram_add_cost_by_dim: HashMap<isize, HashMap<usize, usize>>,
}

impl Reduction {
    pub fn new() -> Self {
        Self {
            reductions: Vec::new()
        }
    }

    pub fn add(&mut self, s: SimplexReduction) {
        self.reductions.push(s);
    }

    pub fn aggregate(&self) -> Aggregate {
        let mut adds = Vec::new();
        for r in self.reductions.iter() {
            for a in r.adds.iter() {
                adds.push((a.this_j, a.other_j));
            }
        }

        let mut avg_adds_required = HashMap::new();
        let mut count = HashMap::new();
        for r in self.reductions.iter() {
            *avg_adds_required.entry(r.dim).or_insert(0.0) += r.adds.len() as f64;
            *count.entry(r.dim).or_insert(0) += 1;
        }
        for (k, &c) in count.iter() {
            *avg_adds_required.get_mut(k).unwrap() /= c as f64;
        }


        let mut add_size_by_dim = HashMap::<isize, Vec<(usize, usize)>>::new();
        for r in self.reductions.iter() {
            if r.adds.len() == 0 { continue; }
            let v = add_size_by_dim.entry(r.dim).or_insert(Vec::new());
            for a in r.adds.iter() {
                v.push((a.this_size, a.other_size));
            }
        }

        let mut avg_add_size_by_dim = HashMap::new();
        for (&dim, adds) in add_size_by_dim.iter() {
            if adds.len() == 0 { continue; }
            let avg_f = adds.iter().map(|(f, _s)| *f).sum::<usize>() as f64 / adds.len() as f64;
            let avg_s = adds.iter().map(|(_f, s)| *s).sum::<usize>() as f64 / adds.len() as f64;
            avg_add_size_by_dim.insert(dim, (avg_f, avg_s));
       	}

       	let mut histogram_add_size_by_dim = HashMap::new();
        for r in self.reductions.iter() {
            if r.adds.len() == 0 { continue; }
            let histogram: &mut HashMap<usize, (usize, usize)> = histogram_add_size_by_dim.entry(r.dim).or_insert(HashMap::new());
            for add in r.adds.iter() {
                histogram.entry(add.this_size).or_insert((0, 0)).0 += 1;
                histogram.entry(add.other_size).or_insert((0, 0)).1 += 1;
            }
       	}

        let mut add_cost_by_dim = HashMap::<isize, Vec<usize>>::new();
        for r in self.reductions.iter() {
            if r.adds.len() == 0 { continue; }
            let v = add_cost_by_dim.entry(r.dim).or_insert(Vec::new());
            for a in r.adds.iter() {
                v.push(a.this_size + a.other_size);
            }
        }

        let mut avg_add_cost_by_dim = HashMap::new();
        for (&dim, adds) in add_cost_by_dim.iter() {
            if adds.len() == 0 { continue; }
            let avg = adds.iter().map(|f| *f).sum::<usize>() as f64 / adds.len() as f64;
            avg_add_cost_by_dim.insert(dim, avg);
       	}

       	let mut histogram_add_cost_by_dim = HashMap::new();
        for r in self.reductions.iter() {
            if r.adds.len() == 0 { continue; }
            let histogram: &mut HashMap<usize, usize> = histogram_add_cost_by_dim.entry(r.dim).or_insert(HashMap::new());
            for add in r.adds.iter() {
                *histogram.entry(add.this_size + add.other_size).or_insert(0) += 1;
            }
       	}


        Aggregate {
            adds,
            avg_adds_required,
            add_size_by_dim,
            avg_add_size_by_dim,
            histogram_add_size_by_dim,
            add_cost_by_dim,
            avg_add_cost_by_dim,
            histogram_add_cost_by_dim,
        }
    }
}

impl Add {
    pub fn regular(this: &Simplex, other: &Simplex) -> Self {
		Self {
    		dim: this.dim,
    		this_size: this.faces.len(),
    		other_size: other.faces.len(),
    		exhaustive: false,
    		this_j: this.j,
    		other_j: other.j,
		}
    }

    pub fn exhaustive(this: &Simplex, other: &Simplex) -> Self {
		Self {
    		dim: this.dim,
    		this_size: this.faces.len(),
    		other_size: other.faces.len(),
    		exhaustive: true,
    		this_j: this.j,
    		other_j: other.j,
		}
    }
}

impl SimplexReduction {
    pub fn new(s: &Simplex) -> Self {
        Self {
            dim: s.dim,
            adds: Vec::new(),
            place_index: None,
        }
    }

	pub fn add(self: &mut Self, add: Add) {
    	self.adds.push(add)
	}
}