Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Sync submodules to tracked branches
run: |
git submodule sync --recursive
git submodule update --init --remote --recursive

- name: Setup Python
id: setup-python
uses: actions/setup-python@v5
Expand All @@ -34,6 +39,35 @@ jobs:
virtualenvs-create: true
virtualenvs-in-project: true

- name: Clean up PATH on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
$clean = ($env:PATH -split ';' | Where-Object {
$_ -notlike '*Git\usr\bin*' -and
$_ -notlike '*Strawberry*'
}) -join ';'
echo "PATH=$clean" >> $env:GITHUB_ENV

- name: Set up MSVC dev cmd
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
with:
toolset: '14.29'
arch: x64

- name: Remove Git link.exe from PATH
if: runner.os == 'Windows'
shell: pwsh
run: |
$gitLink = "C:\Program Files\Git\usr\bin\link.exe"
if (Test-Path $gitLink) {
Rename-Item $gitLink "link_gnu_backup.exe"
Write-Host "Renamed Git link.exe -> link_gnu_backup.exe"
} else {
Write-Host "Git link.exe not found, nothing to do"
}

- name: Cache pip wheels
uses: actions/cache@v4
with:
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/docs_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Sync submodules to tracked branches
run: |
git submodule sync --recursive
git submodule update --init --remote --recursive

- uses: actions/setup-python@v5
with:
python-version: "3.12"
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/docs_preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Sync submodules to tracked branches
run: |
git submodule sync --recursive
git submodule update --init --remote --recursive

- uses: actions/setup-python@v5
with:
python-version: "3.12"
Expand Down
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ __pycache__/

# C extensions
*.so
*.o

# Distribution / packaging
.Python
Expand Down Expand Up @@ -127,7 +128,12 @@ poetry.lock
.cursorindexingignore

# Docs

docs/build/*
docs/source/api/*
docs/source/examples/*

# Log files
*.log

# Unuran build artifacts
src/pysatl_core/sampling/unuran/bindings/_unuran_cffi.c
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "subprojects/unuran-pysatl"]
path = subprojects/unuran-pysatl
url = https://github.com/PySATL/unuran.git
branch = main
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ exclude: >
| LICENSE$
| .*\.md$
| .*\.jpg$
| subprojects/.*
)$

repos:
Expand Down Expand Up @@ -68,3 +69,4 @@ repos:
- scipy>=1.13
- pytest>=8
- scipy-stubs>=1.13
- types-setuptools>=75
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ The library is designed as a **foundational kernel** rather than a ready-to-use
- Python **3.12+** (the project relies on **PEP 695** syntax)
- NumPy **2.x**
- SciPy **1.13+**
- A C toolchain for compiling the UNURAN bindings:
- **Linux/macOS:** GCC (or Clang) plus standard build utilities.
- **Windows:** Microsoft Visual C++ Build Tools (MSVC) from Visual Studio or the standalone Build Tools installer.
- Poetry (recommended for development)

---
Expand All @@ -50,6 +53,7 @@ Clone the repository:
```bash
git clone https://github.com/PySATL/pysatl-core.git
cd pysatl-core
git submodule update --init --remote --recursive
```

### Using Poetry (recommended)
Expand Down
501 changes: 501 additions & 0 deletions examples/example_sampling_methods.ipynb

Large diffs are not rendered by default.

18 changes: 17 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
[build-system]
build-backend = "poetry.core.masonry.api"

requires = [ "poetry-core>=1.9" ]
requires = [
"cffi>=1.16",
"meson>=0.64",
"ninja>=1.10",
"poetry-core>=1.9",
"setuptools>=69",
]

[tool.poetry]
name = "pysatl-core"
Expand Down Expand Up @@ -41,10 +47,15 @@ homepage = "https://github.com/PySATL/pysatl-core"
repository = "https://github.com/PySATL/pysatl-core"
urls.Issues = "https://github.com/PySATL/pysatl-core/issues"

[tool.poetry.build]
script = "src/pysatl_core/sampling/unuran/bindings/_cffi_build.py"

[tool.poetry.dependencies]
python = ">=3.12"
numpy = "^2.0.0"
scipy = ">=1.13"
cffi = "^1.16.0"
mypy_extensions = ">=1.0.0"

[tool.poetry.group.dev.dependencies]
ruff = ">=0.6"
Expand All @@ -55,6 +66,7 @@ coverage = { version = ">=7.5", extras = [ "toml" ] }
pre-commit = ">=3.6"
types-setuptools = "*"
scipy-stubs = ">=1.13.0.0"
types-cffi = ">=1.17.0.0"

[tool.poetry.group.docs.dependencies]
jupyter = "^1.1.1"
Expand All @@ -70,6 +82,7 @@ linkify-it-py = "^2.0.3"
[tool.ruff]
target-version = "py312"
line-length = 100
exclude = [ "subprojects" ]

format.line-ending = "lf"

Expand All @@ -84,6 +97,9 @@ lint.isort.force-single-line = false
lint.isort.known-first-party = [ "pysatl_core" ]
lint.isort.order-by-type = true

[tool.codespell]
skip = "subprojects/**"

[tool.pytest.ini_options]
addopts = "-q --cov=pysatl_core --cov-report=term-missing"
testpaths = [ "tests" ]
Expand Down
4 changes: 4 additions & 0 deletions src/pysatl_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from .distributions import __all__ as _distr_all
from .families import *
from .families import __all__ as _family_all
from .sampling import *
from .sampling import __all__ as _sampling_all
from .types import *
from .types import __all__ as _types_all

Expand All @@ -23,8 +25,10 @@
*_distr_all,
*_family_all,
*_types_all,
*_sampling_all,
]

del _distr_all
del _family_all
del _types_all
del _sampling_all
3 changes: 2 additions & 1 deletion src/pysatl_core/distributions/distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from collections.abc import Mapping
from typing import Any

from pysatl_core.distributions.computation import AnalyticalComputation, Method
from pysatl_core.distributions.computation import AnalyticalComputation
from pysatl_core.distributions.strategies import (
ComputationStrategy,
SamplingStrategy,
Expand All @@ -32,6 +32,7 @@
from pysatl_core.types import (
DistributionType,
GenericCharacteristicName,
Method,
)


Expand Down
4 changes: 2 additions & 2 deletions src/pysatl_core/distributions/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
import numpy as np

from pysatl_core.distributions.registry import characteristic_registry
from pysatl_core.types import CharacteristicName, NumericArray
from pysatl_core.types import CharacteristicName, Method, NumericArray

if TYPE_CHECKING:
from typing import Any

from pysatl_core.distributions.computation import FittedComputationMethod, Method
from pysatl_core.distributions.computation import FittedComputationMethod
from pysatl_core.distributions.distribution import Distribution
from pysatl_core.types import GenericCharacteristicName

Expand Down
26 changes: 26 additions & 0 deletions src/pysatl_core/sampling/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
Public sampling interface re-exporting UNURAN-based defaults.
"""

__author__ = "Artem Romanyuk"
__copyright__ = "Copyright (c) 2025 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"

from .unuran import (
DefaultUnuranSampler,
DefaultUnuranSamplingStrategy,
UnuranMethod,
UnuranMethodConfig,
)

SamplingMethod = UnuranMethod
SamplingMethodConfig = UnuranMethodConfig
DefaultSampler = DefaultUnuranSampler
DefaultSamplingStrategy = DefaultUnuranSamplingStrategy

__all__ = [
"SamplingMethod",
"SamplingMethodConfig",
"DefaultSampler",
"DefaultSamplingStrategy",
]
26 changes: 26 additions & 0 deletions src/pysatl_core/sampling/unuran/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
Expose the UNU.RAN sampling API interfaces alongside their default
implementations backed by our C bindings.
"""

from __future__ import annotations

__author__ = "Artem Romanyuk"
__copyright__ = "Copyright (c) 2025 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"

from .core import (
DefaultUnuranSampler,
DefaultUnuranSamplingStrategy,
)
from .method_config import (
UnuranMethod,
UnuranMethodConfig,
)

__all__ = [
"UnuranMethod",
"UnuranMethodConfig",
"DefaultUnuranSampler",
"DefaultUnuranSamplingStrategy",
]
37 changes: 37 additions & 0 deletions src/pysatl_core/sampling/unuran/bindings/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
PySATL Core — UNU.RAN CFFI Bindings
=====================================

Lazy loader for the compiled CFFI extension module ``_unuran_cffi``.
Tries the fully-qualified package path first, then falls back to a
bare top-level import so the extension can be found regardless of
how it was installed. Exposes ``_unuran_cffi`` (``None`` when the
binary extension is not available).
"""

from __future__ import annotations

__author__ = "Artem Romanyuk"
__copyright__ = "Copyright (c) 2025 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"

from importlib import import_module
from types import ModuleType

_unuran_cffi_module = None

for name in (
"pysatl_core.sampling.unuran.bindings._unuran_cffi",
"_unuran_cffi",
):
try:
_unuran_cffi_module = import_module(name)
break
except ModuleNotFoundError: # pragma: no cover - optional binary module
pass

_unuran_cffi: ModuleType | None = _unuran_cffi_module

__all__ = [
"_unuran_cffi",
]
Loading
Loading