From 4498643b0884a1ef5ee79825e72bb5c1ecdec445 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 07:00:25 +0000 Subject: [PATCH 1/3] docs: use absolute URLs for PyPI README links and add Documentation project URL PyPI renders the README (long_description) at the project root, so repo-relative Markdown links like docs/plot_parity_policy.md resolve to https://pypi.org/project/ovvo-nns/docs/plot_parity_policy.md and 404. - Point all doc links at the live GitHub Pages site (https://ovvo-financial.github.io/NNS-python//), using the file-path-derived URLs that MkDocs actually emits. - Point example/source and LICENSE links at the GitHub repo on main. - Add a Documentation entry to [project.urls] so PyPI's sidebar links to the docs site, and drop the redundant Project URL. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01JsqhFvg51XkvW4pCJquw42 --- README.md | 44 ++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 0c6c564..617bd58 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![PyPI package](https://img.shields.io/badge/package-ovvo--nns-blue)](https://pypi.org/project/ovvo-nns/) [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/) [![Docs](https://img.shields.io/badge/docs-ovvo--financial.github.io-blue)](https://ovvo-financial.github.io/NNS-python/) -[![License](https://img.shields.io/badge/license-GPL--3.0--only-blue)](LICENSE) +[![License](https://img.shields.io/badge/license-GPL--3.0--only-blue)](https://github.com/OVVO-Financial/NNS-python/blob/main/LICENSE) `ovvo-nns` brings Nonlinear Nonparametric Statistics to Python as the `nns` import package. It is a parity-focused port of the R `NNS` 13.0+ package, designed for real-world data that violate symmetry, linearity, or distributional assumptions. @@ -41,7 +41,7 @@ pip install ovvo-nns This includes the matplotlib plotting API (`nns.plotting`); matplotlib is a regular dependency and is imported lazily, so `import nns` stays light. See -[`docs/plot_parity_policy.md`](docs/plot_parity_policy.md). +the [plot parity policy](https://ovvo-financial.github.io/NNS-python/plot_parity_policy/). Use the package as `nns`: @@ -129,7 +129,7 @@ print("forecast:", forecast) | Differentiation | `nns_diff`, `dy_dx`, `dy_d` | | Categorical helpers | `encode_factor_codes`, `factor_2_dummy`, `factor_2_dummy_fr`, `prepare_factor_predictors` | -See [API status](docs/api_status.md) for implemented, partial, guarded, and known-gap paths. +See [API status](https://ovvo-financial.github.io/NNS-python/api_status/) for implemented, partial, guarded, and known-gap paths. ## Design boundaries @@ -143,27 +143,27 @@ Important boundaries: - Direct raw-factor `nns_m_reg(..., factor_2_dummy=True)` is intentionally guarded. Use `prepare_factor_predictors(...)` before `nns_m_reg(...)`. - Compute functions still return values, not figures; passing `plot=True` (where R has it) additionally renders a Matplotlib figure as a side effect via the `nns.plotting` layer, which is color/element-faithful to R but not pixel-diffed. The plot functions can also be called directly on a computed result. -See [behavior conventions](docs/conventions.md) for detailed compatibility notes. +See [behavior conventions](https://ovvo-financial.github.io/NNS-python/conventions/) for detailed compatibility notes. ## Examples Runnable, self-checking example scripts live in -[`examples/vignettes`](examples/vignettes), mirroring the R NNS vignettes. They +[`examples/vignettes`](https://github.com/OVVO-Financial/NNS-python/tree/main/examples/vignettes), mirroring the R NNS vignettes. They are exercised in CI by `tests/docs/test_vignette_examples.py`, so they stay in sync with the package. | Topic | Script | |---|---| -| Overview | [`overview.py`](examples/vignettes/overview.py) | -| Partial moments | [`partial_moments.py`](examples/vignettes/partial_moments.py) | -| Descriptive and distributional tools | [`descriptive_distributional_tools.py`](examples/vignettes/descriptive_distributional_tools.py) | -| Dependence and nonlinear association | [`dependence_nonlinear_association.py`](examples/vignettes/dependence_nonlinear_association.py) | -| Normalization and rescaling | [`normalization_rescaling.py`](examples/vignettes/normalization_rescaling.py) | -| Hypothesis, ANOVA and stochastic superiority | [`hypothesis_anova_stochastic_superiority.py`](examples/vignettes/hypothesis_anova_stochastic_superiority.py) | -| Regression, boosting, stacking and causality | [`regression_boosting_stacking_causality.py`](examples/vignettes/regression_boosting_stacking_causality.py) | -| Time series forecasting | [`time_series_forecasting.py`](examples/vignettes/time_series_forecasting.py) | -| Simulation, bootstrap and risk-neutral | [`simulation_bootstrap_riskneutral.py`](examples/vignettes/simulation_bootstrap_riskneutral.py) | -| Portfolio and stochastic dominance | [`portfolio_stochastic_dominance.py`](examples/vignettes/portfolio_stochastic_dominance.py) | +| Overview | [`overview.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/overview.py) | +| Partial moments | [`partial_moments.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/partial_moments.py) | +| Descriptive and distributional tools | [`descriptive_distributional_tools.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/descriptive_distributional_tools.py) | +| Dependence and nonlinear association | [`dependence_nonlinear_association.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/dependence_nonlinear_association.py) | +| Normalization and rescaling | [`normalization_rescaling.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/normalization_rescaling.py) | +| Hypothesis, ANOVA and stochastic superiority | [`hypothesis_anova_stochastic_superiority.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/hypothesis_anova_stochastic_superiority.py) | +| Regression, boosting, stacking and causality | [`regression_boosting_stacking_causality.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/regression_boosting_stacking_causality.py) | +| Time series forecasting | [`time_series_forecasting.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/time_series_forecasting.py) | +| Simulation, bootstrap and risk-neutral | [`simulation_bootstrap_riskneutral.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/simulation_bootstrap_riskneutral.py) | +| Portfolio and stochastic dominance | [`portfolio_stochastic_dominance.py`](https://github.com/OVVO-Financial/NNS-python/blob/main/examples/vignettes/portfolio_stochastic_dominance.py) | Run one example: @@ -182,12 +182,12 @@ uv run python examples/run_all_vignettes.py The full documentation site is hosted at ****. -- [API reference manual](docs/api_reference.md) -- [API status and known gaps](docs/api_status.md) -- [Behavior conventions and intentional divergences](docs/conventions.md) -- [Parity target, cache regeneration, and automation](docs/parity.md) -- [Benchmarks](docs/benchmarks.md) -- [Examples](examples/vignettes) +- [API reference manual](https://ovvo-financial.github.io/NNS-python/api_reference/) +- [API status and known gaps](https://ovvo-financial.github.io/NNS-python/api_status/) +- [Behavior conventions and intentional divergences](https://ovvo-financial.github.io/NNS-python/conventions/) +- [Parity target, cache regeneration, and automation](https://ovvo-financial.github.io/NNS-python/parity/) +- [Benchmarks](https://ovvo-financial.github.io/NNS-python/benchmarks/) +- [Examples](https://github.com/OVVO-Financial/NNS-python/tree/main/examples/vignettes) ## Development @@ -208,7 +208,7 @@ The default parity suite is cache-backed and does not require `Rscript`. `Rscrip ## Benchmarks -Benchmarks compare selected Python paths with installed R NNS 13.0+ baselines. Many core operations are faster in Python, while some large stochastic-dominance workloads remain faster in R because the R package uses compiled kernels for those paths. See [benchmarks](docs/benchmarks.md) for current measurements and commands. +Benchmarks compare selected Python paths with installed R NNS 13.0+ baselines. Many core operations are faster in Python, while some large stochastic-dominance workloads remain faster in R because the R package uses compiled kernels for those paths. See [benchmarks](https://ovvo-financial.github.io/NNS-python/benchmarks/) for current measurements and commands. ## Authors and contributors diff --git a/pyproject.toml b/pyproject.toml index e788a61..0fa3b90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ keywords = [ "forecasting", "nns", ] -urls = { "Homepage" = "https://github.com/OVVO-Financial/NNS-python", "Repository" = "https://github.com/OVVO-Financial/NNS-python", "Issues" = "https://github.com/OVVO-Financial/NNS-python/issues", "Source" = "https://github.com/OVVO-Financial/NNS-python", "Project" = "https://github.com/OVVO-Financial/NNS-python" } +urls = { "Homepage" = "https://github.com/OVVO-Financial/NNS-python", "Repository" = "https://github.com/OVVO-Financial/NNS-python", "Source" = "https://github.com/OVVO-Financial/NNS-python", "Issues" = "https://github.com/OVVO-Financial/NNS-python/issues", "Documentation" = "https://ovvo-financial.github.io/NNS-python/" } dependencies = [ "matplotlib>=3.7", "numpy", From 2908cf9a8ae57d9eb080e310452b56be45175a1a Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 07:20:12 +0000 Subject: [PATCH 2/3] docs: use exact R NNS export names in API crosswalk The crosswalk and per-function "Closest R API" notes labeled the stochastic-dominance routines as FSD/SSD/TSD and the n-dimensional co-moments descriptively, which do not match the actual R NNS exports. Use the real exported names so the mapping is precise: - FSD/SSD/TSD -> NNS.FSD/NNS.SSD/NNS.TSD (and the .uni variants) - "N-dimensional ... path" -> Co.LPM_nD / Co.UPM_nD / DPM_nD - dy.d -> dy.d_ Applied to both docs/api_reference.md and the ApiMeta source in scripts/generate_api_reference.py that the page is generated from. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01JsqhFvg51XkvW4pCJquw42 --- docs/api_reference.md | 26 +++++++++++++------------- scripts/generate_api_reference.py | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/api_reference.md b/docs/api_reference.md index aa6f112..7575285 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -40,9 +40,9 @@ The generator introspects `nns.__all__`, imports each public object, records sig | Co-moments | `co_upm` | `Co.UPM` | implemented | Pairwise co-upper partial moment. | | Co-moments | `d_lpm` | `D.LPM` | implemented | Pairwise distance lower partial moment. | | Co-moments | `d_upm` | `D.UPM` | implemented | Pairwise distance upper partial moment. | -| Co-moments | `co_lpm_nd` | N-dimensional co-LPM path | implemented | N-dimensional co-lower partial moment wrapper. | -| Co-moments | `co_upm_nd` | N-dimensional co-UPM path | implemented | N-dimensional co-upper partial moment wrapper. | -| Co-moments | `dpm_nd` | N-dimensional DPM path | implemented | N-dimensional directional partial moment wrapper. | +| Co-moments | `co_lpm_nd` | `Co.LPM_nD` | implemented | N-dimensional co-lower partial moment wrapper. | +| Co-moments | `co_upm_nd` | `Co.UPM_nD` | implemented | N-dimensional co-upper partial moment wrapper. | +| Co-moments | `dpm_nd` | `DPM_nD` | implemented | N-dimensional directional partial moment wrapper. | | Classical moments | `ecdf_pm` | ECDF partial-moment helper | implemented | Empirical distribution helper used by moment routines. | | Classical moments | `mean_pm` | `Mean` partial-moment helper | implemented | Mean via partial-moment conventions. | | Classical moments | `var_pm` | `Variance` partial-moment helper | implemented | Variance via partial-moment conventions. | @@ -76,12 +76,12 @@ The generator introspects `nns.__all__`, imports each public object, records sig | Central tendencies | `nns_gravity` | `NNS.gravity` | implemented | NNS gravity center helper. | | Central tendencies | `nns_mode` | `NNS.mode` | implemented | NNS mode helper. | | Central tendencies | `nns_rescale` | `NNS.rescale` | implemented | Rescaling helper. | -| Stochastic dominance | `fsd` | `FSD` | implemented | First-order stochastic dominance. | -| Stochastic dominance | `ssd` | `SSD` | implemented | Second-order stochastic dominance. | -| Stochastic dominance | `tsd` | `TSD` | implemented | Third-order stochastic dominance. | -| Stochastic dominance | `fsd_uni` | `FSD.uni` | implemented | Univariate FSD wrapper. | -| Stochastic dominance | `ssd_uni` | `SSD.uni` | implemented | Univariate SSD wrapper. | -| Stochastic dominance | `tsd_uni` | `TSD.uni` | implemented | Univariate TSD wrapper. | +| Stochastic dominance | `fsd` | `NNS.FSD` | implemented | First-order stochastic dominance. | +| Stochastic dominance | `ssd` | `NNS.SSD` | implemented | Second-order stochastic dominance. | +| Stochastic dominance | `tsd` | `NNS.TSD` | implemented | Third-order stochastic dominance. | +| Stochastic dominance | `fsd_uni` | `NNS.FSD.uni` | implemented | Univariate FSD wrapper. | +| Stochastic dominance | `ssd_uni` | `NNS.SSD.uni` | implemented | Univariate SSD wrapper. | +| Stochastic dominance | `tsd_uni` | `NNS.TSD.uni` | implemented | Univariate TSD wrapper. | | Stochastic dominance | `nns_sd_cluster` | `NNS.SD.cluster` | implemented | Stochastic-dominance clustering. | | Stochastic dominance | `sd_efficient_set` | `SD.efficient.set` | implemented | Stochastic-dominance efficient set. | | Stochastic superiority | `nns_ss` | `NNS.SS` | implemented | Stochastic superiority. | @@ -89,7 +89,7 @@ The generator introspects `nns.__all__`, imports each public object, records sig | Simulation | `nns_meboot` | `NNS.meboot` | implemented | Maximum-entropy bootstrap helper. | | Differentiation | `nns_diff` | `NNS.diff` | implemented | Numerical differentiation. | | Differentiation | `dy_dx` | `dy.dx` | implemented | Scalar derivative helper. | -| Differentiation | `dy_d` | `dy.d` | partial | Multivariate derivative helper. | +| Differentiation | `dy_d` | `dy.d_` | partial | Multivariate derivative helper. | | VaR helpers | `lpm_var` | `LPM.VaR` | implemented | Lower partial-moment VaR helper. | | VaR helpers | `upm_var` | `UPM.VaR` | implemented | Upper partial-moment VaR helper. | @@ -359,13 +359,13 @@ Rescales inputs using NNS conventions. #### `fsd`, `ssd`, `tsd` -Closest R APIs: `FSD`, `SSD`, and `TSD`. +Closest R APIs: `NNS.FSD`, `NNS.SSD`, and `NNS.TSD`. Compute first-, second-, and third-order stochastic dominance. #### `fsd_uni`, `ssd_uni`, `tsd_uni` -Closest R APIs: `FSD.uni`, `SSD.uni`, and `TSD.uni`. +Closest R APIs: `NNS.FSD.uni`, `NNS.SSD.uni`, and `NNS.TSD.uni`. Univariate wrappers for stochastic dominance workflows. @@ -415,7 +415,7 @@ Scalar derivative helper for overall and pointwise evaluation modes. #### `dy_d` -Closest R API: `dy.d`. +Closest R API: `dy.d_`. Multivariate derivative helper. Scalar and vectorized point and distribution modes are covered. Multi-row mixed derivative point matrices use pointwise Python semantics rather than R's order-dependent list-matrix packing quirk. diff --git a/scripts/generate_api_reference.py b/scripts/generate_api_reference.py index e48fc5c..2f5e472 100644 --- a/scripts/generate_api_reference.py +++ b/scripts/generate_api_reference.py @@ -32,9 +32,9 @@ class ApiMeta: "co_upm": ApiMeta("Co-moments", "Co.UPM", "implemented", "Pairwise co-upper partial moment."), "d_lpm": ApiMeta("Co-moments", "D.LPM", "implemented", "Pairwise lower directional partial moment."), "d_upm": ApiMeta("Co-moments", "D.UPM", "implemented", "Pairwise upper directional partial moment."), - "co_lpm_nd": ApiMeta("Co-moments", "N-dimensional co-LPM path", "implemented", "N-dimensional co-lower partial moment wrapper."), - "co_upm_nd": ApiMeta("Co-moments", "N-dimensional co-UPM path", "implemented", "N-dimensional co-upper partial moment wrapper."), - "dpm_nd": ApiMeta("Co-moments", "N-dimensional DPM path", "implemented", "N-dimensional directional partial moment wrapper."), + "co_lpm_nd": ApiMeta("Co-moments", "Co.LPM_nD", "implemented", "N-dimensional co-lower partial moment wrapper."), + "co_upm_nd": ApiMeta("Co-moments", "Co.UPM_nD", "implemented", "N-dimensional co-upper partial moment wrapper."), + "dpm_nd": ApiMeta("Co-moments", "DPM_nD", "implemented", "N-dimensional directional partial moment wrapper."), "ecdf_pm": ApiMeta("Classical moments", "ECDF partial-moment helper", "implemented", "Empirical distribution helper used by moment routines."), "mean_pm": ApiMeta("Classical moments", "Mean partial-moment helper", "implemented", "Mean via partial-moment conventions."), "var_pm": ApiMeta("Classical moments", "Variance partial-moment helper", "implemented", "Variance via partial-moment conventions."), @@ -68,12 +68,12 @@ class ApiMeta: "nns_gravity": ApiMeta("Central tendencies", "NNS.gravity", "implemented", "NNS gravity center helper."), "nns_mode": ApiMeta("Central tendencies", "NNS.mode", "implemented", "NNS mode helper."), "nns_rescale": ApiMeta("Central tendencies", "NNS.rescale", "implemented", "Rescaling helper."), - "fsd": ApiMeta("Stochastic dominance, superiority, and simulation", "FSD", "implemented", "First-order stochastic dominance."), - "ssd": ApiMeta("Stochastic dominance, superiority, and simulation", "SSD", "implemented", "Second-order stochastic dominance."), - "tsd": ApiMeta("Stochastic dominance, superiority, and simulation", "TSD", "implemented", "Third-order stochastic dominance."), - "fsd_uni": ApiMeta("Stochastic dominance, superiority, and simulation", "FSD.uni", "implemented", "Univariate FSD wrapper."), - "ssd_uni": ApiMeta("Stochastic dominance, superiority, and simulation", "SSD.uni", "implemented", "Univariate SSD wrapper."), - "tsd_uni": ApiMeta("Stochastic dominance, superiority, and simulation", "TSD.uni", "implemented", "Univariate TSD wrapper."), + "fsd": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.FSD", "implemented", "First-order stochastic dominance."), + "ssd": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.SSD", "implemented", "Second-order stochastic dominance."), + "tsd": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.TSD", "implemented", "Third-order stochastic dominance."), + "fsd_uni": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.FSD.uni", "implemented", "Univariate FSD wrapper."), + "ssd_uni": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.SSD.uni", "implemented", "Univariate SSD wrapper."), + "tsd_uni": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.TSD.uni", "implemented", "Univariate TSD wrapper."), "nns_sd_cluster": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.SD.cluster", "implemented", "Stochastic-dominance clustering."), "sd_efficient_set": ApiMeta("Stochastic dominance, superiority, and simulation", "SD.efficient.set", "implemented", "Stochastic-dominance efficient set."), "nns_ss": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.SS", "implemented", "Stochastic superiority."), @@ -81,7 +81,7 @@ class ApiMeta: "nns_meboot": ApiMeta("Stochastic dominance, superiority, and simulation", "NNS.meboot", "implemented", "Maximum-entropy bootstrap helper."), "nns_diff": ApiMeta("Differentiation", "NNS.diff", "implemented", "Numerical differentiation."), "dy_dx": ApiMeta("Differentiation", "dy.dx", "implemented", "Scalar derivative helper."), - "dy_d": ApiMeta("Differentiation", "dy.d", "partial", "Multivariate derivative helper."), + "dy_d": ApiMeta("Differentiation", "dy.d_", "partial", "Multivariate derivative helper."), "lpm_var": ApiMeta("VaR helpers", "LPM.VaR", "implemented", "Lower partial-moment VaR helper."), "upm_var": ApiMeta("VaR helpers", "UPM.VaR", "implemented", "Upper partial-moment VaR helper."), } From f7aa2df81a5ea1b4aa75e0856da4673d3fdc8e58 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 07:20:12 +0000 Subject: [PATCH 3/3] release: bump version to 1.0.8 Bump the version consistently across pyproject.toml, nns.__version__, and the README "Current version" row (enforced by scripts/check_version_consistency.py). Provenance in sync/nns_source.json already records the R + NNS-core commits, so a v1.0.8 tag passes scripts/check_release_provenance.py. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01JsqhFvg51XkvW4pCJquw42 --- README.md | 2 +- pyproject.toml | 2 +- src/nns/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 617bd58..6c1ef93 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ NNS is built around partial moments, the lower and upper components of variance, |---|---| | Distribution package | `ovvo-nns` | | Import package | `nns` | -| Current version | `1.0.7` | +| Current version | `1.0.8` | | Python | `>=3.11` | | Required runtime dependencies | NumPy, SciPy | | R required at runtime | No | diff --git a/pyproject.toml b/pyproject.toml index 0fa3b90..2f38388 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ovvo-nns" -version = "1.0.7" +version = "1.0.8" description = "Python port of nonlinear nonparametric statistics from R NNS" readme = "README.md" requires-python = ">=3.11" diff --git a/src/nns/__init__.py b/src/nns/__init__.py index 3957a85..276b6c0 100644 --- a/src/nns/__init__.py +++ b/src/nns/__init__.py @@ -4,7 +4,7 @@ from nns.pm_matrix import pm_matrix as pm_matrix -__version__ = "1.0.7" +__version__ = "1.0.8" _EXPORTS = { "FactorDesign": ("nns.regression", "FactorDesign"),