Skip to content

Commit 9428eca

Browse files
authored
Merge pull request #584 from PyAutoLabs/feature/pointsolver-mcs-headroom
perf(triangles): raise PointSolver MAX_CONTAINING_SIZE 15 → 20 (#583)
2 parents e281abf + 462ad09 commit 9428eca

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

‎autoarray/structures/triangles/array.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from autoarray.structures.triangles.shape import Shape
1111
from autoarray.structures.triangles.shape import _barycentric_contains
1212

13-
MAX_CONTAINING_SIZE = 15
13+
MAX_CONTAINING_SIZE = 20
1414

1515
# Private A/B switch for the step-0 containment route (point-source CPU phase 4b,
1616
# PyAutoArray#579). It only affects `ArrayTriangles` built by

‎test_autoarray/structures/triangles/test_coordinate_jax.py‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,3 +586,61 @@ def containing(vertices, point):
586586
assert all(size < 3 * n * 2 for size in gathered), (
587587
f"step-0 containment gathers {gathered} elements; the triangle array is {3 * n * 2}"
588588
)
589+
590+
591+
# A 16- and a 17-sheet fold: the static lattice's vertices are traced through z -> z**k (z = x + iy),
592+
# so a source point at |w| = 1 has k preimages on the unit circle, each in the interior of exactly one
593+
# traced triangle -- a k-member containing set with no boundary ties. The PointSolver's uncapped
594+
# step-0 maximum on 200 prior draws was 17 (prior draw 12, point-source CPU phase 4c,
595+
# PyAutoArray#583), which the old cap of 15 truncated silently.
596+
FOLD_LIMITS = dict(y_min=-1.3, y_max=1.3, x_min=-1.3, x_max=1.3, scale=0.05)
597+
598+
599+
@pytest.mark.parametrize("sheets", [16, 17])
600+
def test__containing_set_above_the_old_cap_is_not_truncated(sheets):
601+
"""
602+
Under ``jit``, a 16- or 17-triangle containing set keeps every member at the default
603+
`MAX_CONTAINING_SIZE` (20), padded to ``(20,)``; the old cap of 15, passed explicitly, drops
604+
some. Red at ``MAX_CONTAINING_SIZE = 15``.
605+
"""
606+
lattice = _static_lattice(FOLD_LIMITS)
607+
z = lattice.vertices[:, 1] + 1j * lattice.vertices[:, 0]
608+
w = z**sheets
609+
traced = jnp.stack([w.imag, w.real], axis=1)
610+
point = (float(np.sin(0.3)), float(np.cos(0.3)))
611+
612+
uncapped = np.flatnonzero(
613+
np.asarray(Point(*point).mask(lattice.with_vertices(traced).triangles))
614+
)
615+
assert len(uncapped) == sheets
616+
617+
def containing(vertices, max_containing_size=None):
618+
kwargs = (
619+
{}
620+
if max_containing_size is None
621+
else {"max_containing_size": max_containing_size}
622+
)
623+
triangles = triangles_array.ArrayTriangles(
624+
indices=lattice.indices,
625+
vertices=vertices,
626+
step0_layout=lattice.step0_layout,
627+
**kwargs,
628+
)
629+
return triangles.containing_indices(Point(*point))
630+
631+
assert lattice.with_vertices(traced).max_containing_size == MAX_CONTAINING_SIZE
632+
633+
kept = np.asarray(jax.jit(containing)(traced))
634+
assert np.array_equal(np.sort(kept[kept >= 0]), uncapped)
635+
assert kept.shape == (20,)
636+
637+
kept_via_lattice = np.asarray(
638+
jax.jit(lambda v: lattice.with_vertices(v).containing_indices(Point(*point)))(
639+
traced
640+
)
641+
)
642+
assert np.array_equal(kept_via_lattice, kept)
643+
644+
old_cap = np.asarray(jax.jit(lambda v: containing(v, 15))(traced))
645+
assert old_cap.shape == (15,)
646+
assert np.sum(old_cap >= 0) == 15 < sheets

0 commit comments

Comments
 (0)