pointpca2 0.4.2__tar.gz → 0.4.3__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.
@@ -450,12 +450,13 @@ dependencies = [
450
450
 
451
451
  [[package]]
452
452
  name = "pointpca2"
453
- version = "0.4.2"
453
+ version = "0.4.3"
454
454
  dependencies = [
455
455
  "nalgebra",
456
456
  "numpy",
457
457
  "pointpca2-rs",
458
458
  "pyo3",
459
+ "rayon",
459
460
  ]
460
461
 
461
462
  [[package]]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pointpca2"
3
- version = "0.4.2"
3
+ version = "0.4.3"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -10,6 +10,7 @@ crate-type = ["cdylib"]
10
10
  [dependencies]
11
11
  nalgebra = "0.32.5"
12
12
  numpy = "0.15"
13
+ rayon = "1.10.0"
13
14
 
14
15
  [dependencies.pointpca2-rs]
15
16
  git = "https://github.com/akaTsunemori/pointpca2-rs.git"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pointpca2
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Requires-Dist: numpy >=1.26
5
5
  Requires-Dist: toml ==0.10.0
6
6
  License-File: LICENSE
@@ -2,30 +2,30 @@ import numpy as np
2
2
  from .pointpca2 import compute_pointpca2 as __pointpca2_internal
3
3
 
4
4
 
5
- def __preprocess_point_cloud(points, colors):
6
- if type(points) is np.ndarray:
7
- points = np.array(points, dtype=np.double)
8
- if type(colors) is np.ndarray:
9
- colors = np.array(colors, dtype=np.double)
5
+ def __preprocess_point_cloud(
6
+ points: np.ndarray,
7
+ colors: np.ndarray,
8
+ ) -> tuple[np.ndarray, np.ndarray]:
10
9
  if points.shape != colors.shape:
11
10
  raise Exception("Points and colors must have the same shape.")
11
+ if colors.max() <= 1 and colors.min() >= 0 and colors.dtype is np.double:
12
+ colors *= 255
12
13
  if points.dtype != np.double:
13
14
  points = points.astype(np.double)
14
- if colors.max() <= 1 and colors.min() >= 0 and colors.dtype == np.double:
15
- colors *= 255
16
15
  if colors.dtype != np.uint8:
17
16
  colors = colors.astype(np.uint8)
18
17
  return points, colors
19
18
 
20
19
 
21
20
  def compute_pointpca2(
22
- points_reference,
23
- colors_reference,
24
- points_test,
25
- colors_test,
21
+ points_reference: np.ndarray,
22
+ colors_reference: np.ndarray,
23
+ points_test: np.ndarray,
24
+ colors_test: np.ndarray,
26
25
  search_size=81,
26
+ max_workers=0,
27
27
  verbose=False,
28
- ):
28
+ ) -> np.ndarray:
29
29
  """
30
30
  Compute PointPCA2 from reference and test point clouds.
31
31
 
@@ -42,7 +42,13 @@ def compute_pointpca2(
42
42
  search_size : int, optional
43
43
  The k-nearest-neighbors search size.
44
44
  Default is 81.
45
- verbose: bool, optional
45
+ max_workers : int, optional
46
+ Sets the number of threads to be used in the thread-pool.
47
+ If you specify a non-zero number of threads using this parameter, then the
48
+ resulting thread-pools are guaranteed to start at most this number of threads.
49
+ If max_workers is 0, then the number of logical CPUs will be used.
50
+ Default is 0.
51
+ verbose : bool, optional
46
52
  Whether to display verbose information or not.
47
53
  Default is False.
48
54
 
@@ -57,7 +63,7 @@ def compute_pointpca2(
57
63
  the array will eventually be converted to np.double.
58
64
 
59
65
  For the colors arguments, it is expected that the colors are
60
- on the [0, 1] range, or [0, 255]. Other ranges are not supported.
66
+ on the [0, 1] range (np.double), or [0, 255]. Other ranges are not supported.
61
67
  Any dtype is accepted, but the array will eventually be converted
62
68
  to np.uint8.
63
69
 
@@ -69,6 +75,12 @@ def compute_pointpca2(
69
75
  points_a, colors_a = __preprocess_point_cloud(points_reference, colors_reference)
70
76
  points_b, colors_b = __preprocess_point_cloud(points_test, colors_test)
71
77
  predictors = __pointpca2_internal(
72
- points_a, colors_a, points_b, colors_b, search_size, verbose
78
+ points_a,
79
+ colors_a,
80
+ points_b,
81
+ colors_b,
82
+ search_size,
83
+ max_workers,
84
+ verbose,
73
85
  )
74
86
  return predictors
@@ -1,20 +1,16 @@
1
1
  extern crate nalgebra as na;
2
2
  extern crate numpy;
3
3
  extern crate pointpca2_rs;
4
+ extern crate rayon;
5
+
6
+ mod utils;
4
7
 
5
- use na::DMatrix;
6
8
  use numpy::PyArray1;
7
9
  use numpy::PyReadonlyArray2;
8
10
  use pyo3::prelude::*;
9
11
  use pyo3::wrap_pyfunction;
10
-
11
- fn as_dmatrix<'a, T>(x: &'a PyReadonlyArray2<T>) -> DMatrix<T>
12
- where
13
- T: numpy::Element + na::Scalar,
14
- {
15
- let data: Vec<T> = x.as_array().iter().cloned().collect();
16
- DMatrix::from_row_slice(x.shape()[0], x.shape()[1], &data)
17
- }
12
+ use utils::as_dmatrix;
13
+ use utils::set_max_workers;
18
14
 
19
15
  #[pyfunction]
20
16
  fn compute_pointpca2<'py>(
@@ -24,16 +20,14 @@ fn compute_pointpca2<'py>(
24
20
  points_b: PyReadonlyArray2<'py, f64>,
25
21
  colors_b: PyReadonlyArray2<'py, u8>,
26
22
  search_size: usize,
23
+ max_workers: usize,
27
24
  verbose: bool,
28
25
  ) -> &'py PyArray1<f64> {
29
- let (points_a, colors_a, points_b, colors_b) = {
30
- (
31
- as_dmatrix(&points_a),
32
- as_dmatrix(&colors_a),
33
- as_dmatrix(&points_b),
34
- as_dmatrix(&colors_b),
35
- )
36
- };
26
+ set_max_workers(max_workers);
27
+ let points_a = as_dmatrix(points_a);
28
+ let colors_a = as_dmatrix(colors_a);
29
+ let points_b = as_dmatrix(points_b);
30
+ let colors_b = as_dmatrix(colors_b);
37
31
  let pooled_predictors = pointpca2_rs::compute_pointpca2(
38
32
  points_a,
39
33
  colors_a,
@@ -0,0 +1,21 @@
1
+ use na::DMatrix;
2
+ use numpy::PyReadonlyArray2;
3
+ use rayon::ThreadPoolBuilder;
4
+
5
+ pub fn as_dmatrix<T>(x: PyReadonlyArray2<T>) -> DMatrix<T>
6
+ where
7
+ T: numpy::Element + na::Scalar,
8
+ {
9
+ let data: Vec<T> = x.as_array().iter().cloned().collect();
10
+ DMatrix::from_row_slice(x.shape()[0], x.shape()[1], &data)
11
+ }
12
+
13
+ pub fn set_max_workers(max_workers: usize) {
14
+ if max_workers == 0 {
15
+ return;
16
+ }
17
+ ThreadPoolBuilder::new()
18
+ .num_threads(max_workers)
19
+ .build_global()
20
+ .expect("Failed to build global thread pool");
21
+ }
File without changes
File without changes
File without changes
File without changes
File without changes