phimaker 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {phimaker-0.2.0 → phimaker-0.2.2}/Cargo.lock +1 -1
  2. {phimaker-0.2.0 → phimaker-0.2.2}/Cargo.toml +1 -1
  3. {phimaker-0.2.0 → phimaker-0.2.2}/PKG-INFO +1 -1
  4. {phimaker-0.2.0 → phimaker-0.2.2}/pyproject.toml +1 -1
  5. {phimaker-0.2.0 → phimaker-0.2.2}/src/cylinder.rs +6 -3
  6. {phimaker-0.2.0 → phimaker-0.2.2}/src/diagrams.rs +3 -1
  7. {phimaker-0.2.0 → phimaker-0.2.2}/src/ensemble.rs +30 -30
  8. {phimaker-0.2.0 → phimaker-0.2.2}/src/lib.rs +13 -6
  9. {phimaker-0.2.0 → phimaker-0.2.2}/.cargo/config.toml +0 -0
  10. {phimaker-0.2.0 → phimaker-0.2.2}/.github/workflows/python.yml +0 -0
  11. {phimaker-0.2.0 → phimaker-0.2.2}/.gitignore +0 -0
  12. {phimaker-0.2.0 → phimaker-0.2.2}/.gitmodules +0 -0
  13. {phimaker-0.2.0 → phimaker-0.2.2}/README.md +0 -0
  14. {phimaker-0.2.0 → phimaker-0.2.2}/examples/big_test.py +0 -0
  15. {phimaker-0.2.0 → phimaker-0.2.2}/examples/cylinder_test.py +0 -0
  16. {phimaker-0.2.0 → phimaker-0.2.2}/examples/test.py +0 -0
  17. {phimaker-0.2.0 → phimaker-0.2.2}/examples/test_annotated.mat +0 -0
  18. {phimaker-0.2.0 → phimaker-0.2.2}/examples/timing_test.py +0 -0
  19. {phimaker-0.2.0 → phimaker-0.2.2}/examples/torus_test.py +0 -0
  20. {phimaker-0.2.0 → phimaker-0.2.2}/examples/washboard_test.py +0 -0
  21. {phimaker-0.2.0 → phimaker-0.2.2}/fig/5pack.png +0 -0
  22. {phimaker-0.2.0 → phimaker-0.2.2}/fig/5pack_torus.png +0 -0
  23. {phimaker-0.2.0 → phimaker-0.2.2}/fig/pointcloud.png +0 -0
  24. {phimaker-0.2.0 → phimaker-0.2.2}/fig/pointcloud_torus.png +0 -0
  25. {phimaker-0.2.0 → phimaker-0.2.2}/pylock.toml +0 -0
  26. {phimaker-0.2.0 → phimaker-0.2.2}/python/phimaker/__init__.py +0 -0
  27. {phimaker-0.2.0 → phimaker-0.2.2}/python/phimaker/_washboard_interface.py +0 -0
  28. {phimaker-0.2.0 → phimaker-0.2.2}/src/builders.rs +0 -0
  29. {phimaker-0.2.0 → phimaker-0.2.2}/src/indexing.rs +0 -0
  30. {phimaker-0.2.0 → phimaker-0.2.2}/src/overlap.rs +0 -0
  31. {phimaker-0.2.0 → phimaker-0.2.2}/src/utils.rs +0 -0
  32. {phimaker-0.2.0 → phimaker-0.2.2}/uv.lock +0 -0
@@ -272,7 +272,7 @@ dependencies = [
272
272
 
273
273
  [[package]]
274
274
  name = "phimaker"
275
- version = "0.2.0"
275
+ version = "0.2.2"
276
276
  dependencies = [
277
277
  "atomic_refcell",
278
278
  "bincode",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "phimaker"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  edition = "2021"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: phimaker
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -5,7 +5,7 @@ build-backend = "maturin"
5
5
  [project]
6
6
  name = "phimaker"
7
7
  requires-python = ">=3.7"
8
- version = "0.2.0"
8
+ version = "0.2.2"
9
9
  classifiers = [
10
10
  "Programming Language :: Rust",
11
11
  "Programming Language :: Python :: Implementation :: CPython",
@@ -1,5 +1,6 @@
1
1
  use lophat::columns::{Column, VecColumn};
2
2
  use pyo3::prelude::*;
3
+ use log::debug;
3
4
 
4
5
  use std::cmp::Ordering;
5
6
 
@@ -43,6 +44,7 @@ pub struct CylinderMetadata {
43
44
  pub domain_shift: Vec<usize>,
44
45
  }
45
46
 
47
+ // Build the filtered mapping cylinder of a map between filtered chain complexes.
46
48
  pub fn build_cylinder(
47
49
  domain_matrix: Vec<(f64, VecColumn)>,
48
50
  codomain_matrix: Vec<(f64, VecColumn)>,
@@ -67,7 +69,7 @@ pub fn build_cylinder(
67
69
  .into_iter()
68
70
  .enumerate()
69
71
  .map(|(idx, (time, col))| {
70
- // Make two copies of each domain column
72
+ // First copy of domain columns
71
73
  (idx, time, CylinderColType::Domain, col.clone())
72
74
  });
73
75
 
@@ -75,7 +77,7 @@ pub fn build_cylinder(
75
77
  .into_iter()
76
78
  .enumerate()
77
79
  .map(|(idx, (time, col))| {
78
- // Make two copies of each domain column
80
+ // Second copy of domain columns
79
81
  (idx, time, CylinderColType::DomainShifted, col)
80
82
  });
81
83
 
@@ -136,7 +138,7 @@ pub fn build_cylinder(
136
138
  .entries()
137
139
  .map(|row_idx|
138
140
  codomain_idxs.get(row_idx)
139
- .expect("Map must be compatibile with both filtrations i.e. entrance time of f(c) <= entrance time of c")
141
+ .expect("Map must be compatible with both filtrations i.e. entrance time of f(c) <= entrance time of c")
140
142
  )
141
143
  .copied();
142
144
  let domain_shift_part = col
@@ -180,6 +182,7 @@ pub fn build_cylinder(
180
182
  codomain: codomain_idxs,
181
183
  domain_shift: domain_shift_idxs,
182
184
  };
185
+ debug!("Built mapping cylinder with {} simplices.", cylinder_matrix.len());
183
186
  (cylinder_matrix, metadata)
184
187
  }
185
188
 
@@ -1,6 +1,8 @@
1
1
  use bincode::deserialize_from;
2
2
  use std::{fs::File, io::BufReader};
3
3
 
4
+ use log::debug;
5
+
4
6
  use lophat::{
5
7
  algorithms::RVDecomposition, columns::Column, utils::PersistenceDiagram, utils::RVDFileFormat,
6
8
  };
@@ -214,7 +216,7 @@ impl FileEnsemble {
214
216
  let at_diagram = f_decomp.diagram();
215
217
  at_diagram.anti_transpose(self.metadata.size_of_k)
216
218
  };
217
- println!("Got f");
219
+ debug!("Got f");
218
220
  let f_negative_list = compute_negative_list(&self.metadata, &f_diagram);
219
221
  let rel_diagram = {
220
222
  let rel_decomp = from_file(&self.rel);
@@ -1,7 +1,7 @@
1
1
  use bincode::serialize_into;
2
+ use log::debug;
2
3
  use serde::Serialize;
3
4
  use std::{fs::File, io::BufWriter, marker::PhantomData, thread};
4
- use log::info;
5
5
 
6
6
  use lophat::{
7
7
  algorithms::RVDecomposition,
@@ -31,18 +31,18 @@ pub struct EnsembleMetadata {
31
31
  #[derive(Debug)]
32
32
  pub struct DecompositionEnsemble<C, Algo>
33
33
  where
34
- C: Column,
35
- Algo: RVDecomposition<C>,
36
- {
37
- pub f: Algo,
38
- pub g: Algo,
39
- pub im: Algo,
40
- pub ker: Algo,
41
- pub cok: Algo,
42
- pub rel: Algo,
43
- pub metadata: EnsembleMetadata,
44
- phantom: PhantomData<C>,
45
- }
34
+ C: Column,
35
+ Algo: RVDecomposition<C>,
36
+ {
37
+ pub f: Algo,
38
+ pub g: Algo,
39
+ pub im: Algo,
40
+ pub ker: Algo,
41
+ pub cok: Algo,
42
+ pub rel: Algo,
43
+ pub metadata: EnsembleMetadata,
44
+ phantom: PhantomData<C>,
45
+ }
46
46
 
47
47
  #[derive(Debug)]
48
48
  pub struct FileEnsemble {
@@ -64,9 +64,9 @@ pub fn thread_1_job<Algo: RVDecomposition<VecColumn, Options = LoPhatOptions> +
64
64
  ) -> Algo {
65
65
  // Decompose Df
66
66
  // Df is a chain complex so can compute anti-transpose instead
67
- let df_at = anti_transpose(&df);
67
+ let df_at = anti_transpose(df);
68
68
  let out = Algo::decompose(df_at.into_iter(), Some(base_options));
69
- info!("Decomposed f");
69
+ debug!("Decomposed f");
70
70
  out
71
71
  }
72
72
 
@@ -78,17 +78,17 @@ pub fn thread_2_job<Algo: RVDecomposition<VecColumn, Options = LoPhatOptions> +
78
78
  ) -> (Algo, Algo) {
79
79
  // Decompose Dg
80
80
  // Need to use v columns of Dg later, so no AT
81
- let dg = build_dg(&df, &g_elements, &l_first_mapping);
82
- let mut dg_options = base_options.clone();
81
+ let dg = build_dg(df, g_elements, l_first_mapping);
82
+ let mut dg_options = base_options;
83
83
  dg_options.maintain_v = true;
84
84
  let decomp_dg = Algo::decompose(dg, Some(dg_options));
85
- info!("Decomposed g");
85
+ debug!("Decomposed g");
86
86
  // Decompose dcok
87
- let dcok = build_dcok(&df, &decomp_dg, &g_elements, l_first_mapping);
88
- let mut dcok_options = base_options.clone();
87
+ let dcok = build_dcok(df, &decomp_dg, g_elements, l_first_mapping);
88
+ let mut dcok_options = base_options;
89
89
  dcok_options.clearing = false; // Not a chain complex
90
90
  let decompose_dcok = Algo::decompose(dcok, Some(dcok_options));
91
- info!("Decomposed cok");
91
+ debug!("Decomposed cok");
92
92
  (decomp_dg, decompose_dcok)
93
93
  }
94
94
  pub fn thread_3_job<Algo: RVDecomposition<VecColumn, Options = LoPhatOptions> + Send>(
@@ -99,20 +99,20 @@ pub fn thread_3_job<Algo: RVDecomposition<VecColumn, Options = LoPhatOptions> +
99
99
  ) -> (Algo, Algo, VectorMapping) {
100
100
  // Decompose dim
101
101
  // Need to use v columns of Dim later, also no AT or clearing since D^2 != 0
102
- let dim = build_dim(&df, l_first_mapping);
103
- let mut dim_options = base_options.clone();
102
+ let dim = build_dim(df, l_first_mapping);
103
+ let mut dim_options = base_options;
104
104
  dim_options.maintain_v = true;
105
105
  dim_options.clearing = false;
106
106
  let decompose_dim = Algo::decompose(dim, Some(dim_options));
107
- info!("Decomposed im");
107
+ debug!("Decomposed im");
108
108
  // Decompose dker
109
109
  let dker = build_dker(&decompose_dim, l_first_mapping);
110
- let mut dker_options = base_options.clone();
110
+ let mut dker_options = base_options;
111
111
  dker_options.clearing = false; // Not a chain complex so no clearing
112
112
  dker_options.column_height = Some(size_of_k); // Non-square matrix
113
113
  let decompose_dker = Algo::decompose(dker, Some(dker_options));
114
114
  let kernel_mapping = build_kernel_mapping(&decompose_dim);
115
- info!("Decomposed ker");
115
+ debug!("Decomposed ker");
116
116
  (decompose_dim, decompose_dker, kernel_mapping)
117
117
  }
118
118
 
@@ -123,12 +123,12 @@ pub fn thread_4_job<Algo: RVDecomposition<VecColumn, Options = LoPhatOptions> +
123
123
  size_of_k: usize,
124
124
  base_options: LoPhatOptions,
125
125
  ) -> (Algo, VectorMapping) {
126
- let (rel_mapping, l_index) = build_rel_mapping(&df, &g_elements, size_of_l, size_of_k);
127
- let drel = build_drel(&df, &g_elements, &rel_mapping, l_index).collect();
126
+ let (rel_mapping, l_index) = build_rel_mapping(df, g_elements, size_of_l, size_of_k);
127
+ let drel = build_drel(df, g_elements, &rel_mapping, l_index).collect();
128
128
  // Chain complex so can use clearing and AT
129
129
  let drel_at = anti_transpose(&drel);
130
130
  let decompose_drel = Algo::decompose(drel_at.into_iter(), Some(base_options));
131
- info!("Decomposed rel");
131
+ debug!("Decomposed rel");
132
132
  (decompose_drel, rel_mapping)
133
133
  }
134
134
 
@@ -199,7 +199,7 @@ pub fn to_file<Algo: Serialize>(algo: Algo) -> File {
199
199
  let mut buf = BufWriter::new(&mut file_write);
200
200
  serialize_into(&mut buf, &algo).expect("Can serialize to file");
201
201
  }
202
- // Explicity release memory
202
+ // Explicitly release memory
203
203
  drop(algo);
204
204
  file_read
205
205
  }
@@ -27,7 +27,7 @@ fn compute_ensemble(
27
27
  num_threads: usize,
28
28
  slow: bool,
29
29
  ) -> DiagramEnsemble {
30
- let annotated_matrix = matrix
30
+ let annotated_matrix: Vec<_> = matrix
31
31
  .into_iter()
32
32
  .map(|(in_g, dimension, boundary)| AnnotatedColumn {
33
33
  in_g,
@@ -64,15 +64,15 @@ fn compute_ensemble(
64
64
  /// - If `map` is not compatible with the domain matrix, i.e., if the entrance time of any
65
65
  /// generator in the domain is less than the entrance time of any generators in its image under
66
66
  /// $f$.
67
-
68
67
  #[pyfunction]
69
- #[pyo3(signature = (domain_matrix, codomain_matrix, map, num_threads=0))]
68
+ #[pyo3(signature = (domain_matrix, codomain_matrix, map, num_threads=0, slow=false))]
70
69
  fn compute_ensemble_cylinder(
71
70
  py: Python<'_>,
72
71
  domain_matrix: Vec<(f64, usize, Vec<usize>)>,
73
72
  codomain_matrix: Vec<(f64, usize, Vec<usize>)>,
74
73
  map: Vec<Vec<usize>>,
75
74
  num_threads: usize,
75
+ slow: bool,
76
76
  ) -> (DiagramEnsemble, CylinderMetadata) {
77
77
  // We mark each map with the dimension of the domain column
78
78
  let map = map
@@ -89,9 +89,16 @@ fn compute_ensemble_cylinder(
89
89
  .map(|(time, dimension, boundary)| (time, VecColumn::from((dimension, boundary))))
90
90
  .collect();
91
91
  let (cylinder, metadata) = build_cylinder(domain_matrix, codomain_matrix, map);
92
- let decomps =
93
- py.allow_threads(|| all_decompositions::<LockFreeAlgorithm<_>>(cylinder, num_threads));
94
- (decomps.all_diagrams(), metadata)
92
+ if slow {
93
+ let decomps =
94
+ all_decompositions_slow::<LockFreeAlgorithm<_>>(cylinder, num_threads);
95
+ (decomps.all_diagrams(), metadata)
96
+ } else {
97
+ let decomps = py.allow_threads(|| {
98
+ all_decompositions::<LockFreeAlgorithm<_>>(cylinder, num_threads)
99
+ });
100
+ (decomps.all_diagrams(), metadata)
101
+ }
95
102
  }
96
103
 
97
104
  #[pyfunction]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes