pyterp 0.1.0__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.
pyterp-0.1.0/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Jonathan Motta
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ graft src
pyterp-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyterp
3
+ Version: 0.1.0
4
+ Summary: A package for performing optimized k-NN IDW interpolation using C++.
5
+ Author: Jonathan Motta
6
+ Author-email: Jonathan Motta <jonathangmotta98@gmail.com>
7
+ Project-URL: Homepage, https://github.com/jgmotta98/PyTerp
8
+ Project-URL: Bug Tracker, https://github.com/jgmotta98/PyTerp/issues
9
+ Project-URL: Source Code, https://github.com/jgmotta98/PyTerp
10
+ Keywords: interpolation,k-NN,IDW,C++,parallel,numpy,performance
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Topic :: Scientific/Engineering :: GIS
16
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: C++
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: numpy
26
+ Dynamic: author
27
+ Dynamic: license-file
28
+
29
+ # PyTerp
30
+
31
+ A 3D interpolator for **Python** designed for maximum speed on large datasets. It accelerates the IDW algorithm with a parallelized C++ core (`OpenMP`) and optimized k-NN searches (`nanoflann`).
32
+
33
+ ## Theoretical Summary
34
+
35
+ The interpolation is performed in a two-step process that combines the k-NN and IDW algorithms.
36
+
37
+ 1. **Neighbor Selection (k-NN)**: For each point where a value is to be estimated, the _k-Nearest Neighbors_ algorithm first finds the k closest known source points in space. The efficiency of this search is ensured by an optimized data structure (`k-d tree`).
38
+
39
+ 2. **Value Calculation (IDW)**: Next, the _Inverse Distance Weighting_ method calculates the final value as a weighted average of the k found neighbors. The weight of each neighbor is inversely proportional to its distance (weight = 1/distanceᵖ, where `p` is a power parameter), causing closer points to have a much greater influence on the result.
40
+
41
+ ## Prerequisites
42
+
43
+ Before you begin, ensure you have the following software installed:
44
+
45
+ * **Python 3.10+**
46
+ * **Git**
47
+ * **A C++ compiler**: This package contains C++ code that needs to be compiled during installation.
48
+ * **Windows**: Install Visual Studio Build Tools (select the "Desktop development with C++" workload).
49
+ * **Linux (Debian/Ubuntu)**: Install build-essential with: sudo apt-get install build-essential.
50
+
51
+ ## Installation
52
+
53
+ ### PyPI
54
+
55
+ #### Install the package:
56
+
57
+ ```bash
58
+ pip install pyterp
59
+ ```
60
+
61
+ ---
62
+
63
+ ### GitHub
64
+
65
+ #### 1. Clone the repository:
66
+
67
+ ```bash
68
+ git clone https://github.com/jgmotta98/PyTerp.git
69
+ cd PyTerp
70
+ ```
71
+
72
+ #### 2. Create and activate a virtual environment:
73
+
74
+ ```bash
75
+ # Create the environment
76
+ python -m venv .venv
77
+
78
+ # Activate the environment
79
+ # On Windows (cmd.exe):
80
+ .venv\Scripts\activate
81
+ # On macOS/Linux (bash/zsh):
82
+ source .venv/bin/activate
83
+ ```
84
+
85
+ #### 3. Install the requirements:
86
+
87
+ ```bash
88
+ pip install -r requirements.txt
89
+ ```
90
+
91
+ #### 4. Install the package:
92
+
93
+ ```bash
94
+ pip install .
95
+ ```
96
+
97
+ ## Usage Example
98
+
99
+ ```py
100
+ import numpy as np
101
+ import pyterp as pt
102
+
103
+ # Assuming 'source_points', 'source_values', and 'target_points'
104
+ # are properly prepared NumPy arrays.
105
+ interpolated_values = pt.interpolate(
106
+ source_points=source_points,
107
+ source_values=source_values,
108
+ target_points=target_points,
109
+ k_neighbors=10,
110
+ power=2
111
+ )
112
+
113
+ print("Interpolated values:", interpolated_values)
114
+ ```
115
+
116
+ For a complete and runnable example, including the creation and preparation of input data, please see the script in the [examples](examples/basic_usage.py) folder.
117
+
118
+ ## Acknowledgements
119
+
120
+ This project uses `nanoflann`, a high-performance C++ library for the _k-Nearest Neighbors_ algorithm. The efficiency of nanoflann's k-d tree implementation is fundamental to this interpolator's performance.
121
+
122
+ * **Official Repository:** [Nanoflann](https://github.com/jlblancoc/nanoflann)
pyterp-0.1.0/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # PyTerp
2
+
3
+ A 3D interpolator for **Python** designed for maximum speed on large datasets. It accelerates the IDW algorithm with a parallelized C++ core (`OpenMP`) and optimized k-NN searches (`nanoflann`).
4
+
5
+ ## Theoretical Summary
6
+
7
+ The interpolation is performed in a two-step process that combines the k-NN and IDW algorithms.
8
+
9
+ 1. **Neighbor Selection (k-NN)**: For each point where a value is to be estimated, the _k-Nearest Neighbors_ algorithm first finds the k closest known source points in space. The efficiency of this search is ensured by an optimized data structure (`k-d tree`).
10
+
11
+ 2. **Value Calculation (IDW)**: Next, the _Inverse Distance Weighting_ method calculates the final value as a weighted average of the k found neighbors. The weight of each neighbor is inversely proportional to its distance (weight = 1/distanceᵖ, where `p` is a power parameter), causing closer points to have a much greater influence on the result.
12
+
13
+ ## Prerequisites
14
+
15
+ Before you begin, ensure you have the following software installed:
16
+
17
+ * **Python 3.10+**
18
+ * **Git**
19
+ * **A C++ compiler**: This package contains C++ code that needs to be compiled during installation.
20
+ * **Windows**: Install Visual Studio Build Tools (select the "Desktop development with C++" workload).
21
+ * **Linux (Debian/Ubuntu)**: Install build-essential with: sudo apt-get install build-essential.
22
+
23
+ ## Installation
24
+
25
+ ### PyPI
26
+
27
+ #### Install the package:
28
+
29
+ ```bash
30
+ pip install pyterp
31
+ ```
32
+
33
+ ---
34
+
35
+ ### GitHub
36
+
37
+ #### 1. Clone the repository:
38
+
39
+ ```bash
40
+ git clone https://github.com/jgmotta98/PyTerp.git
41
+ cd PyTerp
42
+ ```
43
+
44
+ #### 2. Create and activate a virtual environment:
45
+
46
+ ```bash
47
+ # Create the environment
48
+ python -m venv .venv
49
+
50
+ # Activate the environment
51
+ # On Windows (cmd.exe):
52
+ .venv\Scripts\activate
53
+ # On macOS/Linux (bash/zsh):
54
+ source .venv/bin/activate
55
+ ```
56
+
57
+ #### 3. Install the requirements:
58
+
59
+ ```bash
60
+ pip install -r requirements.txt
61
+ ```
62
+
63
+ #### 4. Install the package:
64
+
65
+ ```bash
66
+ pip install .
67
+ ```
68
+
69
+ ## Usage Example
70
+
71
+ ```py
72
+ import numpy as np
73
+ import pyterp as pt
74
+
75
+ # Assuming 'source_points', 'source_values', and 'target_points'
76
+ # are properly prepared NumPy arrays.
77
+ interpolated_values = pt.interpolate(
78
+ source_points=source_points,
79
+ source_values=source_values,
80
+ target_points=target_points,
81
+ k_neighbors=10,
82
+ power=2
83
+ )
84
+
85
+ print("Interpolated values:", interpolated_values)
86
+ ```
87
+
88
+ For a complete and runnable example, including the creation and preparation of input data, please see the script in the [examples](examples/basic_usage.py) folder.
89
+
90
+ ## Acknowledgements
91
+
92
+ This project uses `nanoflann`, a high-performance C++ library for the _k-Nearest Neighbors_ algorithm. The efficiency of nanoflann's k-d tree implementation is fundamental to this interpolator's performance.
93
+
94
+ * **Official Repository:** [Nanoflann](https://github.com/jlblancoc/nanoflann)
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=61.0",
4
+ "wheel",
5
+ "pybind11>=2.10"
6
+ ]
7
+ build-backend = "setuptools.build_meta"
8
+
9
+ [project]
10
+ name = "pyterp"
11
+ version = "0.1.0"
12
+ authors = [
13
+ { name="Jonathan Motta", email="jonathangmotta98@gmail.com" },
14
+ ]
15
+ description = "A package for performing optimized k-NN IDW interpolation using C++."
16
+ readme = "README.md"
17
+ requires-python = ">=3.10"
18
+ keywords = [
19
+ "interpolation",
20
+ "k-NN",
21
+ "IDW",
22
+ "C++",
23
+ "parallel",
24
+ "numpy",
25
+ "performance"
26
+ ]
27
+ classifiers = [
28
+ "Development Status :: 3 - Alpha",
29
+
30
+ "Intended Audience :: Science/Research",
31
+ "Intended Audience :: Developers",
32
+
33
+ "Operating System :: OS Independent",
34
+
35
+ "Topic :: Scientific/Engineering :: GIS",
36
+ "Topic :: Scientific/Engineering :: Mathematics",
37
+ "Topic :: Software Development :: Libraries :: Python Modules",
38
+
39
+ "Programming Language :: Python :: 3.10",
40
+ "Programming Language :: Python :: 3.11",
41
+ "Programming Language :: Python :: 3.12",
42
+ "Programming Language :: C++",
43
+ ]
44
+ dependencies = [
45
+ "numpy",
46
+ ]
47
+
48
+ [project.urls]
49
+ Homepage = "https://github.com/jgmotta98/PyTerp"
50
+ "Bug Tracker" = "https://github.com/jgmotta98/PyTerp/issues"
51
+ "Source Code" = "https://github.com/jgmotta98/PyTerp"
pyterp-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
pyterp-0.1.0/setup.py ADDED
@@ -0,0 +1,37 @@
1
+ from setuptools import setup, Extension, find_packages
2
+ import sys
3
+ import pybind11
4
+ import os
5
+
6
+ _SRC_PATH = "src"
7
+
8
+
9
+ cpp_extension = Extension(
10
+ name='pyterp',
11
+ sources=[os.path.join(_SRC_PATH, 'interpolator.cpp')],
12
+ include_dirs=[
13
+ _SRC_PATH,
14
+ pybind11.get_include(),
15
+ ],
16
+ language='c++',
17
+ extra_compile_args=['/O2', '/openmp'] if sys.platform == 'win32' else ['-O3', '-fopenmp'],
18
+ )
19
+
20
+
21
+ with open("README.md", "r", encoding="utf-8") as fh:
22
+ long_description = fh.read()
23
+
24
+
25
+ setup(
26
+ name='pyterp',
27
+ version='0.1.0',
28
+ author='Jonathan Motta',
29
+ author_email='jonathangmotta98@gmail.com',
30
+ description='A package for performing optimized k-NN IDW interpolation using C++.',
31
+ long_description=long_description,
32
+ long_description_content_type="text/markdown",
33
+ package_dir={'': 'src'},
34
+ packages=find_packages(where='src'),
35
+ ext_modules=[cpp_extension],
36
+ zip_safe=False,
37
+ )
@@ -0,0 +1,102 @@
1
+ #include <pybind11/pybind11.h>
2
+ #include <pybind11/numpy.h>
3
+ #include <vector>
4
+ #include <omp.h>
5
+
6
+ #include "nanoflann.hpp"
7
+
8
+ namespace py = pybind11;
9
+
10
+ struct NumpyAdaptor {
11
+ const py::detail::unchecked_reference<double, 2> &data;
12
+ const size_t n_rows;
13
+
14
+ NumpyAdaptor(const py::detail::unchecked_reference<double, 2> &d) : data(d), n_rows(d.shape(0)) {}
15
+
16
+ inline size_t kdtree_get_point_count() const { return n_rows; }
17
+
18
+ inline double kdtree_get_pt(const size_t idx, const size_t dim) const { return data(idx, dim); }
19
+
20
+ template <class BBOX> bool kdtree_get_bbox(BBOX&) const { return false; }
21
+ };
22
+
23
+
24
+ py::array_t<double> cpp_interpolate(
25
+ py::array_t<double, py::array::c_style | py::array::forcecast> source_pts,
26
+ py::array_t<double, py::array::c_style | py::array::forcecast> source_vals,
27
+ py::array_t<double, py::array::c_style | py::array::forcecast> target_pts,
28
+ int k_neighbors,
29
+ double power)
30
+ {
31
+ if (source_pts.ndim() != 2 || source_pts.shape(1) != 3)
32
+ throw std::runtime_error("Source points must be an Nx3 array.");
33
+ if (target_pts.ndim() != 2 || target_pts.shape(1) != 3)
34
+ throw std::runtime_error("Target points must be an Mx3 array.");
35
+ if (source_vals.ndim() != 1 || source_vals.shape(0) != source_pts.shape(0))
36
+ throw std::runtime_error("Source values must be a 1D array matching the number of source points.");
37
+
38
+ auto source_pts_ptr = source_pts.unchecked<2>();
39
+ auto source_vals_ptr = source_vals.unchecked<1>();
40
+ auto target_pts_ptr = target_pts.unchecked<2>();
41
+
42
+ const size_t n_sources = source_pts.shape(0);
43
+ const size_t n_targets = target_pts.shape(0);
44
+
45
+ NumpyAdaptor source_cloud(source_pts_ptr);
46
+ typedef nanoflann::KDTreeSingleIndexAdaptor<
47
+ nanoflann::L2_Simple_Adaptor<double, NumpyAdaptor>,
48
+ NumpyAdaptor,
49
+ 3
50
+ > kd_tree_t;
51
+
52
+ kd_tree_t index(3, source_cloud, nanoflann::KDTreeSingleIndexAdaptorParams(10));
53
+ index.buildIndex();
54
+
55
+ py::array_t<double> interpolated_vals(n_targets);
56
+ auto interpolated_vals_ptr = interpolated_vals.mutable_unchecked<1>();
57
+
58
+ #pragma omp parallel for schedule(dynamic)
59
+ for (long long i = 0; i < n_targets; ++i) {
60
+ double query_pt[3] = {target_pts_ptr(i, 0), target_pts_ptr(i, 1), target_pts_ptr(i, 2)};
61
+
62
+ std::vector<unsigned int> ret_index(k_neighbors);
63
+ std::vector<double> out_dist_sqr(k_neighbors);
64
+ index.knnSearch(&query_pt[0], k_neighbors, &ret_index[0], &out_dist_sqr[0]);
65
+
66
+ double total_weight = 0.0;
67
+ double weighted_sum = 0.0;
68
+
69
+ for (size_t j = 0; j < k_neighbors; ++j) {
70
+ const unsigned int neighbor_idx = ret_index[j];
71
+ const double dist = std::sqrt(out_dist_sqr[j]);
72
+
73
+ if (dist < 1e-9) {
74
+ weighted_sum = source_vals_ptr(neighbor_idx);
75
+ total_weight = 1.0;
76
+ break;
77
+ }
78
+
79
+ const double weight = 1.0 / std::pow(dist, power);
80
+ weighted_sum += source_vals_ptr(neighbor_idx) * weight;
81
+ total_weight += weight;
82
+ }
83
+
84
+ if (total_weight > 1e-9) {
85
+ interpolated_vals_ptr(i) = weighted_sum / total_weight;
86
+ } else {
87
+ interpolated_vals_ptr(i) = 0.0;
88
+ }
89
+ }
90
+
91
+ return interpolated_vals;
92
+ }
93
+
94
+ PYBIND11_MODULE(pyterp, m) {
95
+ m.doc() = "A high-performance parallel interpolator using C++, OpenMP, and pybind11";
96
+ m.def("interpolate", &cpp_interpolate, "Interpolates scattered 3D data onto target points using parallel k-NN IDW",
97
+ py::arg("source_points"),
98
+ py::arg("source_values"),
99
+ py::arg("target_points"),
100
+ py::arg("k_neighbors") = 8,
101
+ py::arg("power") = 2.0);
102
+ }