Speed up rasterization ~40x and large solves ~2x
- Hybrid rasterizer: PIL scanline fill for the bulk, with cells in a ~2 px band around each ring edge re-tested exactly against the polygon - cell-for-cell identical to the old center-in-polygon pass (equivalence test added) but O(vertices + cells) instead of O(vertices x cells). Measured 4.5 s -> 0.11 s at 1.45M cells with 8.8k polygon vertices. - AMG-preconditioned CG (pyamg, new requirement) above 500k unknowns: measured 7.0 s vs 15.3 s spsolve at 1.4M unknowns at a fraction of the memory, R identical to 1e-6; the old Jacobi-CG (kept as fallback when pyamg is missing) needed tens of minutes there. spsolve stays the default below 500k where it is exact and fastest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+12
-1
@@ -79,10 +79,21 @@ def test_hole_increases_resistance_and_converges():
|
||||
assert abs(r_a.R_ohm - r_b.R_ohm) < 0.01 * r_b.R_ohm
|
||||
|
||||
|
||||
def test_cg_path_matches_direct(monkeypatch):
|
||||
def test_iterative_paths_match_direct(monkeypatch):
|
||||
"""AMG-CG (default iterative) and Jacobi-CG (pyamg-missing fallback)
|
||||
both reproduce the direct solve."""
|
||||
p = strip_problem(length=50, width=10, e_len=5)
|
||||
r_direct, _ = _solve(p, 0.25)
|
||||
monkeypatch.setattr(config, "SPSOLVE_MAX_UNKNOWNS", 0)
|
||||
r_amg, _ = _solve(p, 0.25)
|
||||
assert r_amg.solve_info.method == "amg+cg"
|
||||
assert r_amg.R_ohm == pytest.approx(r_direct.R_ohm, rel=1e-6)
|
||||
assert r_amg.mismatch_rel < 1e-5
|
||||
|
||||
def no_pyamg(A, b):
|
||||
raise ImportError("pyamg unavailable")
|
||||
|
||||
monkeypatch.setattr(solver, "_solve_amg", no_pyamg)
|
||||
r_cg, _ = _solve(p, 0.25)
|
||||
assert r_cg.solve_info.method == "cg+jacobi"
|
||||
assert r_cg.R_ohm == pytest.approx(r_direct.R_ohm, rel=1e-6)
|
||||
|
||||
Reference in New Issue
Block a user