Skip to content

Commit 28aa7ef

Browse files
Migrate package identity to NNS
1 parent bf5f190 commit 28aa7ef

179 files changed

Lines changed: 564 additions & 543 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/native-backend-ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ jobs:
3232
run: python -m pip install -e .
3333

3434
- name: Run native import smoke test
35-
run: python -c "import pynns._nnscore as c; print(c.lpm(2.0, 0.0, [-2.0, -1.0, 0.5, 3.0]))"
35+
run: python -c "import nns._nnscore as c; print(c.lpm(2.0, 0.0, [-2.0, -1.0, 0.5, 3.0]))"
3636

3737
- name: Run invariants without Rscript
3838
run: python -m pytest -q tests/invariants
3939

4040
- name: Run parity from committed R cache
41-
run: PYNNS_R_CACHE_ONLY=1 python -m pytest -q tests/parity
41+
run: NNS_R_CACHE_ONLY=1 python -m pytest -q tests/parity
4242

4343
- name: Run ruff
4444
run: ruff check .

CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.18)
22

3-
project(pynns_native LANGUAGES CXX)
3+
project(nns_native LANGUAGES CXX)
44

55
set(CMAKE_CXX_STANDARD 17)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -18,7 +18,7 @@ add_subdirectory(extern/NNS-core)
1818
# it can be linked into the nanobind module on ELF platforms.
1919
set_target_properties(nnscore PROPERTIES POSITION_INDEPENDENT_CODE ON)
2020

21-
nanobind_add_module(_nnscore src/pynns/_nnscore_bindings.cpp)
21+
nanobind_add_module(_nnscore src/nns/_nnscore_bindings.cpp)
2222
target_link_libraries(_nnscore PRIVATE nnscore)
2323
target_compile_features(_nnscore PRIVATE cxx_std_17)
24-
install(TARGETS _nnscore LIBRARY DESTINATION pynns)
24+
install(TARGETS _nnscore LIBRARY DESTINATION nns)

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# PyNNS
1+
# NNS Python
22

33
Python port of the R NNS 12.1 beta package.
44

5-
- PyPI package: `nns-pm`
6-
- Import name: `pynns`
5+
- Distribution package: `NNS`
6+
- Import package: `nns` (`import nns`)
7+
- Native extension: `nns._nnscore`
78
- Runtime dependencies: NumPy, SciPy
89
- R required for normal use: no
910
- Status: alpha, parity-focused
@@ -12,14 +13,14 @@ Python port of the R NNS 12.1 beta package.
1213
## Install
1314

1415
```bash
15-
pip install nns-pm
16+
pip install NNS
1617
```
1718

1819
## Quick Use
1920

2021
```python
2122
import numpy as np
22-
from pynns import lpm, nns_dep, nns_reg
23+
from nns import lpm, nns_dep, nns_reg
2324

2425
x = np.array([-2.0, -1.0, 0.5, 3.0])
2526
downside = lpm(2, 0.0, x)
@@ -47,7 +48,7 @@ uv run ruff check .
4748
uv run mypy
4849
```
4950

50-
R and the R `NNS` package are only needed to regenerate parity fixtures.
51+
CI parity is cache-backed through committed fixtures and does not require `Rscript`. `Rscript` and the R `NNS` package are only needed for local cache regeneration. The parity claim is bounded by committed fixtures and cache entries; full R package parity is not claimed, and plot artifacts are intentionally out of scope.
5152

5253
## Attribution
5354

docs/api_status.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# PyNNS API Status
1+
# NNS Python API Status
22

3-
This page summarizes the public PyNNS API surface, known gaps, guarded paths,
3+
This page summarizes the public NNS Python API surface, known gaps, guarded paths,
44
and design boundaries.
55

6-
PyNNS is an alpha, parity-focused Python port of installed R NNS 12.1 beta,
6+
NNS Python is an alpha, parity-focused Python port of installed R NNS 12.1 beta,
77
implemented natively in Python on top of NumPy and SciPy. It does not
88
wrap R, call the R package at runtime, or depend on compiled R/C++ shims. The
99
goal is public input/output compatibility where R behavior is stable,
@@ -17,7 +17,7 @@ largest remaining API work is now mostly ergonomic: categorical predictor
1717
preparation is explicit through `prepare_factor_predictors(...)`, while direct
1818
raw-factor `nns_m_reg(..., factor_2_dummy=True)` remains guarded because the
1919
installed R internal path errors. Named R data-frame factor ordering quirks are
20-
documented as outside PyNNS' positional-column API boundary. Performance gaps
20+
documented as outside NNS Python' positional-column API boundary. Performance gaps
2121
remain mostly in large stochastic-dominance workloads where R uses compiled
2222
kernels.
2323

@@ -57,7 +57,7 @@ invariant, and property coverage.
5757
| Nowcast panel: `nns_nowcast_panel` | implemented | medium | Python-native deterministic monthly panel helper backed by `nns_var`. R NNS 12.1 beta removed `NNS.nowcast`, so this is no longer an R-export parity target. |
5858
| Providers: `CsvNowcastProvider` | implemented | medium | Produces explicit local/offline payloads for `nns_nowcast_panel`. |
5959
| Bootstrap/Monte Carlo: `nns_meboot`, `nns_mc` | implemented | medium | Deterministic diagnostics are parity-tested; exact stochastic replicate parity with R is not expected. |
60-
| Stochastic dominance/superiority: `fsd`, `ssd`, `tsd`, `.uni` wrappers, `nns_ss`, `nns_sd_cluster`, `sd_efficient_set` | implemented | medium | Public structures and deterministic paths are covered. SD uses exact pure-NumPy prefix-pair kernels plus a degree-1 discrete order-statistic matrix path; R's C++ core remains faster on full finance fixtures. Stochastic intervals use PyNNS RNG. |
60+
| Stochastic dominance/superiority: `fsd`, `ssd`, `tsd`, `.uni` wrappers, `nns_ss`, `nns_sd_cluster`, `sd_efficient_set` | implemented | medium | Public structures and deterministic paths are covered. SD uses exact pure-NumPy prefix-pair kernels plus a degree-1 discrete order-statistic matrix path; R's C++ core remains faster on full finance fixtures. Stochastic intervals use NNS Python RNG. |
6161
| ANOVA: `nns_anova` | implemented | high | Binary, multi-group, pairwise, and degenerate `NaN` conventions are covered. |
6262
| Normalization: `nns_norm` | implemented | high | Numeric matrix path is implemented. |
6363
| Categorical helpers: `encode_factor_codes`, `factor_2_dummy`, `factor_2_dummy_fr`, `prepare_factor_predictors` | implemented | high | Explicit `levels=` / `factor_levels=` should be used to reproduce R factor ordering. `prepare_factor_predictors(...)` exposes the regression-ready full-rank design matrix path. |
@@ -69,24 +69,24 @@ invariant, and property coverage.
6969
| Area | Path | Current behavior | Reason / next action |
7070
|---|---|---|---|
7171
| Multivariate regression | direct `factor_2_dummy=True` raw predictor path | Guarded with `NotImplementedError` in direct `nns_m_reg(..., factor_2_dummy=True)`. | Installed R direct `NNS.M.reg` raw factor input errors. Use `prepare_factor_predictors(...)` first, or use the public `nns_reg(..., factor_2_dummy=True, factor_levels=...)` expansion path. |
72-
| Boost | `threshold` on the `n_features > 10` stochastic path | Guarded with `NotImplementedError` on the high-feature stochastic epoch path. | Installed R errors because `test.features` is never built. PyNNS keeps this explicit. |
73-
| Boost/factor predictors | named data-frame factor predictor ordering | Deferred, not represented as a named-column API. | PyNNS uses positional `X1`, `X2`, ... semantics. Installed R named data frames can reorder columns alphabetically before `data.matrix`. |
72+
| Boost | `threshold` on the `n_features > 10` stochastic path | Guarded with `NotImplementedError` on the high-feature stochastic epoch path. | Installed R errors because `test.features` is never built. NNS Python keeps this explicit. |
73+
| Boost/factor predictors | named data-frame factor predictor ordering | Deferred, not represented as a named-column API. | NNS Python uses positional `X1`, `X2`, ... semantics. Installed R named data frames can reorder columns alphabetically before `data.matrix`. |
7474

7575
## Intentional Design Boundaries
7676

7777
- No hidden network fetching happens by default.
78-
- PyNNS does not export `nns_nowcast`; R NNS 12.1 beta removed `NNS.nowcast`.
78+
- NNS Python does not export `nns_nowcast`; R NNS 12.1 beta removed `NNS.nowcast`.
7979
- Nowcast providers are payload builders for `nns_nowcast_panel`, not implicit
8080
public forecast wrappers.
8181
- `CsvNowcastProvider` is local/offline.
8282
- Library code does not auto-load `.env` files.
8383
- External data clients and dataframe libraries are not dependencies.
84-
- PyNNS uses explicit Python errors for some cases where R silently truncates,
84+
- NNS Python uses explicit Python errors for some cases where R silently truncates,
8585
coerces, warns, or returns unusable values. Important divergences are recorded
8686
in `docs/conventions.md`.
8787
- Stochastic exact stream parity is not expected. Stochastic paths use NumPy RNG
8888
and are tested structurally/statistically.
89-
- Plotting side effects from R APIs are generally ignored; PyNNS returns data.
89+
- Plotting side effects from R APIs are generally ignored; NNS Python returns data.
9090
- Stochastic-dominance performance work stays pure NumPy for alpha. The current
9191
implementation mirrors R's sorted-column/prefix-sum algorithm and adds
9292
Python-specific guard pruning, kept-only active-set scans for degree 2/3 and
@@ -100,15 +100,15 @@ Nowcast provider support is explicit. Providers return payloads; callers pass
100100
the payload to `nns_nowcast_panel`:
101101

102102
```python
103-
from pynns import nns_nowcast_panel
104-
from pynns.providers import CsvNowcastProvider
103+
from nns import nns_nowcast_panel
104+
from nns.providers import CsvNowcastProvider
105105

106106
provider = CsvNowcastProvider("monthly_panel.csv")
107107
payload = provider.fetch((), "2000-01-03")
108108
result = nns_nowcast_panel(payload["series"], h=2, tau=12, dates=payload["dates"])
109109
```
110110

111-
PyNNS does not ship a default Yahoo, FRED, or other live-data workflow hidden
111+
NNS Python does not ship a default Yahoo, FRED, or other live-data workflow hidden
112112
behind a public nowcast wrapper.
113113

114114
## Intentional Divergences And Caveats
@@ -120,7 +120,7 @@ examples include:
120120
- Co-moment length mismatches raise `ValueError`; R warns, truncates, and divides
121121
by the longer length.
122122
- Factor and class labels are explicit. R factor levels become numeric codes;
123-
PyNNS callers should pass `levels=` or `class_levels=` when ordering matters.
123+
NNS Python callers should pass `levels=` or `class_levels=` when ordering matters.
124124
- Public outputs use NumPy arrays and plain dictionaries instead of R
125125
`data.table` objects.
126126
- Some installed-R quirks are intentionally matched when they affect stable
@@ -131,14 +131,14 @@ examples include:
131131
stage. Strict xfails track current installed-R deviations in the Iris
132132
classification vignette, the documented ARMA numeric multi-lag weighting
133133
divergence, and VAR's ARMA-derived univariate/ensemble outputs. The Iris
134-
classification xfail mixes two different issues: PyNNS stack predicts the
134+
classification xfail mixes two different issues: NNS Python stack predicts the
135135
correct held-out class where installed R NNS 12.1 rounds the same borderline
136136
estimate down, while boost remains a true output disparity whose installed-R
137-
and PyNNS balanced predictions both miss the held-out class.
137+
and NNS Python balanced predictions both miss the held-out class.
138138

139139
## Release-Relevant Caveats
140140

141-
- PyNNS is alpha. The public API is parity-focused but not declared stable.
141+
- NNS Python is alpha. The public API is parity-focused but not declared stable.
142142
- This is not full R parity yet.
143143
- `dy_d` scalar and vectorized point/distribution modes are covered on focused
144144
fixtures. Multi-row mixed derivative point matrices intentionally use
@@ -150,11 +150,11 @@ examples include:
150150
## Internal Or Out Of Scope
151151

152152
Some R NNS helper names are implementation details or lower-level surfaces in
153-
the R package rather than APIs PyNNS should expose one-for-one. Examples include
153+
the R package rather than APIs NNS Python should expose one-for-one. Examples include
154154
`NNS.ANOVA.bin`, `Uni.caus`, compiled `*_cpp` shims, sampling helpers, and
155155
generated-vector helpers.
156156

157-
PyNNS implements the corresponding behavior natively in Python where it is
157+
NNS Python implements the corresponding behavior natively in Python where it is
158158
needed by public APIs. It does not mirror every R helper name as a top-level
159159
Python export. Matrix-style public behavior is exposed where supported through
160160
Python names such as `causal_matrix`; not exposing an exact R helper name does

docs/benchmarks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ baseline so Python/R comparisons remain visible when R has not been rerun.
123123
Run only the realistic Python benchmarks with:
124124

125125
```bash
126-
PYNNS_OFFLINE=1 uv run pytest -q -n0 -m benchmark --benchmark-enable \
126+
NNS_OFFLINE=1 uv run pytest -q -n0 -m benchmark --benchmark-enable \
127127
--benchmark-json=docs/benchmark_reports/realistic_sd_python_latest.json \
128128
tests/benchmarks/test_stochastic_dominance_realistic.py \
129129
tests/benchmarks/test_finance_sd_rolling.py \
@@ -195,5 +195,5 @@ Interpretation:
195195
- The implementation deliberately follows R's C++ SD algorithmic structure:
196196
sorted columns, prefix sums, pair-threshold dominance checks, exact guards, and
197197
no tolerance-based shortcuts.
198-
- Full-fixture PyNNS runs are feasible for research iteration, but R's C++ SD
198+
- Full-fixture NNS Python runs are feasible for research iteration, but R's C++ SD
199199
core remains materially faster on the largest cluster cases.

0 commit comments

Comments
 (0)