Source code for polytopax

"""PolytopAX: JAX-based computational geometry library.

A high-performance convex hull computation and polytope manipulation library
built on the JAX ecosystem with support for automatic differentiation and GPU acceleration.

Features:
- Differentiable approximate convex hull computation
- JAX-native implementation for GPU/TPU acceleration
- Compatible with jit, grad, vmap, and other JAX transformations
- Object-oriented and functional APIs
- Geometric predicates and polytope operations

Examples:
    Basic usage:
        >>> import polytopax as ptx
        >>> import jax.numpy as jnp
        >>> points = jnp.array([[0, 0], [1, 0], [0, 1], [1, 1]])
        >>> hull_vertices = ptx.convex_hull(points)

    Object-oriented API:
        >>> hull = ptx.ConvexHull.from_points(points)
        >>> print(f"Volume: {hull.volume()}")

    Machine learning integration:
        >>> import jax
        >>> grad_fn = jax.grad(lambda pts: ptx.ConvexHull.from_points(pts).volume())
"""

__version__ = "0.0.1"
__author__ = "PolytopAX Development Team"

# Core imports - using lazy loading to avoid circular imports
_CORE_AVAILABLE = True
_import_error = None


def _lazy_import():
    """Lazy import to avoid circular dependencies."""
    global _CORE_AVAILABLE, _import_error
    if _import_error:
        return False

    try:
        # Test import to check for circular dependencies
        from .core.polytope import ConvexHull  # noqa: F401
        from .core.utils import (  # noqa: F401
            generate_direction_vectors,
            remove_duplicate_points,
            scale_to_unit_ball,
            validate_point_cloud,
        )
        from .operations.predicates import (  # noqa: F401
            convex_hull_surface_area,
            convex_hull_volume,
            distance_to_convex_hull,
            hausdorff_distance,
            point_in_convex_hull,
        )

        return True
    except ImportError as e:
        _CORE_AVAILABLE = False
        _import_error = e
        print(f"Warning: Core PolytopAX functionality not available: {e}")
        return False


def __getattr__(name):
    """Lazy attribute access for imported modules."""
    if not _lazy_import():
        raise AttributeError(f"module '{__name__}' has no attribute '{name}' (core functionality unavailable)")

    # Handle hull functions
    if name in ("convex_hull", "approximate_convex_hull"):
        from .core.hull import approximate_convex_hull, convex_hull

        if name == "convex_hull":
            return convex_hull
        elif name == "approximate_convex_hull":
            return approximate_convex_hull

    # Handle approximation algorithms
    elif name in (
        "approximate_hull_advanced",
        "batched_approximate_hull",
        "multi_resolution_hull",
        "progressive_hull_refinement",
    ):
        from .algorithms.approximation import (
            approximate_convex_hull as approximate_hull_advanced,
        )
        from .algorithms.approximation import (
            batched_approximate_hull,
            multi_resolution_hull,
            progressive_hull_refinement,
        )

        return {
            "approximate_hull_advanced": approximate_hull_advanced,
            "batched_approximate_hull": batched_approximate_hull,
            "multi_resolution_hull": multi_resolution_hull,
            "progressive_hull_refinement": progressive_hull_refinement,
        }[name]

    # Handle core classes
    elif name == "ConvexHull":
        from .core.polytope import ConvexHull

        return ConvexHull

    # Handle utilities
    elif name in (
        "generate_direction_vectors",
        "remove_duplicate_points",
        "scale_to_unit_ball",
        "validate_point_cloud",
    ):
        from .core.utils import (
            generate_direction_vectors,
            remove_duplicate_points,
            scale_to_unit_ball,
            validate_point_cloud,
        )

        return {
            "generate_direction_vectors": generate_direction_vectors,
            "remove_duplicate_points": remove_duplicate_points,
            "scale_to_unit_ball": scale_to_unit_ball,
            "validate_point_cloud": validate_point_cloud,
        }[name]

    # Handle predicates
    elif name in (
        "convex_hull_surface_area",
        "convex_hull_volume",
        "distance_to_convex_hull",
        "hausdorff_distance",
        "point_in_convex_hull",
    ):
        from .operations.predicates import (
            convex_hull_surface_area,
            convex_hull_volume,
            distance_to_convex_hull,
            hausdorff_distance,
            point_in_convex_hull,
        )

        return {
            "convex_hull_surface_area": convex_hull_surface_area,
            "convex_hull_volume": convex_hull_volume,
            "distance_to_convex_hull": distance_to_convex_hull,
            "hausdorff_distance": hausdorff_distance,
            "point_in_convex_hull": point_in_convex_hull,
        }[name]

    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")


# Version and metadata
__all__ = [
    "__author__",
    "__version__",
]

# Core functions will be available through __getattr__
__all__.extend(
    [
        "ConvexHull",
        "approximate_convex_hull",
        # Advanced algorithms
        "approximate_hull_advanced",
        "batched_approximate_hull",
        # Main interface
        "convex_hull",
        "convex_hull_surface_area",
        "convex_hull_volume",
        "distance_to_convex_hull",
        "generate_direction_vectors",
        "hausdorff_distance",
        "multi_resolution_hull",
        "point_in_convex_hull",
        "progressive_hull_refinement",
        "remove_duplicate_points",
        "scale_to_unit_ball",
        "validate_point_cloud",
    ]
)


# Expose version at package level
def get_version():
    """Get PolytopAX version string."""
    return __version__


[docs] def get_info(): """Get PolytopAX package information.""" # Test if core functionality is available core_available = _lazy_import() info = { "version": __version__, "author": __author__, "core_available": core_available, "description": "JAX-based computational geometry library", } if core_available: info["available_functions"] = len(__all__) - 2 # Exclude version and author return info