Skip to content

Commit ca4ffb3

Browse files
committed
chore: license, gitignore, pyproject cleanup
1 parent db9954a commit ca4ffb3

8 files changed

Lines changed: 138 additions & 91 deletions

File tree

‎.gitignore‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
target/
1+
.claude/
2+
.mypy_cache/
23
.venv
3-
*.so
4-
*.dylib
4+
/target/
55
__pycache__/
6-
.claude/
6+
*.dylib
7+
*.egg-info/
8+
*.pyc
9+
*.pyd
10+
*.so
11+
dist/

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ crate-type = ["cdylib", "rlib"]
1717
criterion = "0.5"
1818

1919
[dependencies]
20-
pyo3 = { version = "0.23", features = ["extension-module", "abi3-py311"] }
20+
pyo3 = { version = "0.23", features = ["extension-module", "abi3-py310"] }
2121
numpy = "0.23"
2222
nalgebra = "0.33"
2323
thiserror = "2"

‎LICENSE‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) python-adaptive contributors
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

‎benches/bench_triangulation.rs‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ fn generate_points(dim: usize, count: usize, seed: u64) -> Vec<Vec<f64>> {
1818
for index in 0..count {
1919
let mut point = Vec::with_capacity(dim);
2020
for axis in 0..dim {
21-
let low_discrepancy = ((index + 1) as f64 * (axis + 2) as f64 * 0.618_033_988_749_894_9)
22-
.fract();
21+
let low_discrepancy =
22+
((index + 1) as f64 * (axis + 2) as f64 * 0.618_033_988_749_894_9).fract();
2323
let jitter = next_unit_f64(&mut state);
24-
point.push(0.7 * low_discrepancy + 0.3 * jitter + axis as f64 * 1e-4 + index as f64 * 1e-12);
24+
point.push(
25+
0.7 * low_discrepancy + 0.3 * jitter + axis as f64 * 1e-4 + index as f64 * 1e-12,
26+
);
2527
}
2628
points.push(point);
2729
}
@@ -140,11 +142,7 @@ fn add_point_bench(c: &mut Criterion) {
140142

141143
fn circumsphere_benches(c: &mut Criterion) {
142144
let mut group = c.benchmark_group("circumsphere");
143-
let simplex_2d = vec![
144-
vec![0.0, 0.0],
145-
vec![0.9, 0.1],
146-
vec![0.2, 0.8],
147-
];
145+
let simplex_2d = vec![vec![0.0, 0.0], vec![0.9, 0.1], vec![0.2, 0.8]];
148146
let simplex_3d = vec![
149147
vec![0.0, 0.0, 0.0],
150148
vec![1.0, 0.1, 0.0],
@@ -174,7 +172,9 @@ fn point_in_circumcircle_bench(c: &mut Criterion) {
174172
let mut current = triangulation.clone();
175173
let pt_index = insert_pending_vertex(&mut current, point.clone());
176174
let start = Instant::now();
177-
let inside = current.point_in_circumcircle(pt_index, &simplex, &None).unwrap();
175+
let inside = current
176+
.point_in_circumcircle(pt_index, &simplex, &None)
177+
.unwrap();
178178
black_box(inside);
179179
total += start.elapsed();
180180
}
@@ -198,7 +198,7 @@ fn locate_and_containing_benches(c: &mut Criterion) {
198198
.collect();
199199
let faces: Vec<Simplex> = simplices
200200
.iter()
201-
.map(|simplex| simplex[..triangulation.dim].iter().copied().collect())
201+
.map(|simplex| simplex[..triangulation.dim].to_vec())
202202
.collect();
203203

204204
group.bench_function("locate_point", |b| {

‎pyproject.toml‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ name = "adaptive-triangulation"
77
dynamic = ["version"]
88
description = "Fast N-dimensional Delaunay triangulation with incremental point insertion"
99
readme = "README.md"
10+
authors = [{ name = "python-adaptive contributors" }]
1011
license = "BSD-3-Clause"
11-
requires-python = ">=3.11"
12+
requires-python = ">=3.10"
1213
classifiers = [
1314
"Development Status :: 3 - Alpha",
1415
"Intended Audience :: Science/Research",
1516
"License :: OSI Approved :: BSD License",
1617
"Programming Language :: Python :: 3",
18+
"Programming Language :: Python :: 3.10",
19+
"Programming Language :: Python :: 3.11",
20+
"Programming Language :: Python :: 3.12",
21+
"Programming Language :: Python :: 3.13",
22+
"Programming Language :: Python :: 3.14",
1723
"Programming Language :: Python :: Implementation :: CPython",
1824
"Programming Language :: Rust",
1925
"Topic :: Scientific/Engineering :: Mathematics",
@@ -27,6 +33,7 @@ test = ["pytest>=7.0", "scipy>=1.10"]
2733

2834
[project.urls]
2935
Homepage = "https://github.com/python-adaptive/adaptive-triangulation"
36+
Issues = "https://github.com/python-adaptive/adaptive-triangulation/issues"
3037
Repository = "https://github.com/python-adaptive/adaptive-triangulation"
3138

3239
[tool.maturin]

‎src/geometry.rs‎

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,7 @@ pub fn matrix_rank(vectors: &[Vec<f64>], tol: f64) -> Result<usize, GeometryErro
126126
let rows = vectors.len();
127127
let flat: Vec<f64> = vectors.iter().flat_map(|row| row.iter().copied()).collect();
128128
let svd = DMatrix::from_row_slice(rows, cols, &flat).svd(false, false);
129-
let max_singular = svd
130-
.singular_values
131-
.iter()
132-
.copied()
133-
.fold(0.0_f64, f64::max);
129+
let max_singular = svd.singular_values.iter().copied().fold(0.0_f64, f64::max);
134130
let tol = if tol.is_sign_positive() {
135131
tol
136132
} else {
@@ -155,24 +151,25 @@ pub fn fast_2d_point_in_simplex(
155151
let [[p0x, p0y], [p1x, p1y], [p2x, p2y]] = *simplex;
156152
let [px, py] = *point;
157153

158-
let area: f64 = 0.5
159-
* (-p1y * p2x + p0y * (p2x - p1x) + p1x * p2y + p0x * (p1y - p2y));
154+
let area: f64 = 0.5 * (-p1y * p2x + p0y * (p2x - p1x) + p1x * p2y + p0x * (p1y - p2y));
160155
if area == 0.0 {
161156
return Err(GeometryError::DegenerateSimplex);
162157
}
163158

164-
let s = 1.0 / (2.0 * area)
165-
* (p0y * p2x + (p2y - p0y) * px - p0x * p2y + (p0x - p2x) * py);
159+
let s = 1.0 / (2.0 * area) * (p0y * p2x + (p2y - p0y) * px - p0x * p2y + (p0x - p2x) * py);
166160
if s < -eps || s > 1.0 + eps {
167161
return Ok(false);
168162
}
169163

170-
let t = 1.0 / (2.0 * area)
171-
* (p0x * p1y + (p0y - p1y) * px - p0y * p1x + (p1x - p0x) * py);
164+
let t = 1.0 / (2.0 * area) * (p0x * p1y + (p0y - p1y) * px - p0y * p1x + (p1x - p0x) * py);
172165
Ok(t >= -eps && s + t <= 1.0 + eps)
173166
}
174167

175-
pub fn point_in_simplex(point: &[f64], simplex: &[Vec<f64>], eps: f64) -> Result<bool, GeometryError> {
168+
pub fn point_in_simplex(
169+
point: &[f64],
170+
simplex: &[Vec<f64>],
171+
eps: f64,
172+
) -> Result<bool, GeometryError> {
176173
if simplex.is_empty() || simplex.len() != point.len() + 1 {
177174
return Err(GeometryError::InvalidDimensions(
178175
"Simplex dimension mismatch".to_string(),
@@ -247,14 +244,10 @@ pub fn fast_3d_circumsphere(points: &[[f64; 3]; 4]) -> ([f64; 3], f64) {
247244
let l2 = x2 * x2 + y2 * y2 + z2 * z2;
248245
let l3 = x3 * x3 + y3 * y3 + z3 * z3;
249246

250-
let dx = l1 * (y2 * z3 - z2 * y3) - l2 * (y1 * z3 - z1 * y3)
251-
+ l3 * (y1 * z2 - z1 * y2);
252-
let dy = l1 * (x2 * z3 - z2 * x3) - l2 * (x1 * z3 - z1 * x3)
253-
+ l3 * (x1 * z2 - z1 * x2);
254-
let dz = l1 * (x2 * y3 - y2 * x3) - l2 * (x1 * y3 - y1 * x3)
255-
+ l3 * (x1 * y2 - y1 * x2);
256-
let aa = x1 * (y2 * z3 - z2 * y3) - x2 * (y1 * z3 - z1 * y3)
257-
+ x3 * (y1 * z2 - z1 * y2);
247+
let dx = l1 * (y2 * z3 - z2 * y3) - l2 * (y1 * z3 - z1 * y3) + l3 * (y1 * z2 - z1 * y2);
248+
let dy = l1 * (x2 * z3 - z2 * x3) - l2 * (x1 * z3 - z1 * x3) + l3 * (x1 * z2 - z1 * x2);
249+
let dz = l1 * (x2 * y3 - y2 * x3) - l2 * (x1 * y3 - y1 * x3) + l3 * (x1 * y2 - y1 * x2);
250+
let aa = x1 * (y2 * z3 - z2 * y3) - x2 * (y1 * z3 - z1 * y3) + x3 * (y1 * z2 - z1 * y2);
258251
let a = 2.0 * aa;
259252

260253
let cx = dx / a;
@@ -344,8 +337,8 @@ fn slogdet(matrix: &[Vec<f64>]) -> Result<(f64, f64), GeometryError> {
344337
for pivot_col in 0..n {
345338
let mut pivot_row = pivot_col;
346339
let mut pivot_abs = work[pivot_col][pivot_col].abs();
347-
for row in (pivot_col + 1)..n {
348-
let candidate = work[row][pivot_col].abs();
340+
for (row, values) in work.iter().enumerate().skip(pivot_col + 1) {
341+
let candidate = values[pivot_col].abs();
349342
if candidate > pivot_abs {
350343
pivot_abs = candidate;
351344
pivot_row = row;
@@ -368,11 +361,12 @@ fn slogdet(matrix: &[Vec<f64>]) -> Result<(f64, f64), GeometryError> {
368361
sign *= pivot.signum();
369362
log_abs_det += pivot.abs().ln();
370363

371-
for row in (pivot_col + 1)..n {
372-
let factor = work[row][pivot_col] / pivot;
373-
work[row][pivot_col] = 0.0;
374-
for col in (pivot_col + 1)..n {
375-
work[row][col] -= factor * work[pivot_col][col];
364+
let pivot_values = work[pivot_col].clone();
365+
for row_values in work.iter_mut().skip(pivot_col + 1) {
366+
let factor = row_values[pivot_col] / pivot;
367+
row_values[pivot_col] = 0.0;
368+
for (col, value) in row_values.iter_mut().enumerate().skip(pivot_col + 1) {
369+
*value -= factor * pivot_values[col];
376370
}
377371
}
378372
}
@@ -450,9 +444,11 @@ pub fn simplex_volume_in_embedding(vertices: &[Vec<f64>]) -> Result<f64, Geometr
450444

451445
let n = vertices.len();
452446
let mut matrix = vec![vec![0.0; n + 1]; n + 1];
453-
for idx in 1..=n {
454-
matrix[0][idx] = 1.0;
455-
matrix[idx][0] = 1.0;
447+
for value in matrix[0].iter_mut().skip(1) {
448+
*value = 1.0;
449+
}
450+
for row in matrix.iter_mut().skip(1) {
451+
row[0] = 1.0;
456452
}
457453
for row in 0..n {
458454
for col in 0..n {

‎src/lib.rs‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,10 @@ fn _rust(m: &Bound<'_, PyModule>) -> PyResult<()> {
5151

5252
#[pyfunction]
5353
#[pyo3(name = "circumsphere")]
54-
fn py_circumsphere(
55-
py: Python<'_>,
56-
points: &Bound<'_, PyAny>,
57-
) -> PyResult<(Py<PyTuple>, f64)> {
54+
fn py_circumsphere(py: Python<'_>, points: &Bound<'_, PyAny>) -> PyResult<(Py<PyTuple>, f64)> {
5855
let points = parse_points_sized(points, "Please provide a 2-dimensional list of points")?;
59-
let (center, radius) = geom::circumsphere(&points).map_err(|err| PyValueError::new_err(err.to_string()))?;
56+
let (center, radius) =
57+
geom::circumsphere(&points).map_err(|err| PyValueError::new_err(err.to_string()))?;
6058
Ok((point_tuple(py, &center), radius))
6159
}
6260

0 commit comments

Comments
 (0)