Skip to content

Commit aeacbbe

Browse files
Merge pull request #48 from OVVO-Financial/claude/exciting-tesla-hn7ymn
Add hosted documentation site (MkDocs Material, pkgdown-style)
2 parents a8f6b24 + 2a43294 commit aeacbbe

11 files changed

Lines changed: 521 additions & 0 deletions

File tree

.github/workflows/docs.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Docs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "docs/**"
8+
- "mkdocs.yml"
9+
- ".github/workflows/docs.yml"
10+
workflow_dispatch:
11+
12+
# Allow only one concurrent deployment, and let in-progress runs finish.
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: false
16+
17+
permissions:
18+
contents: read
19+
pages: write
20+
id-token: write
21+
22+
jobs:
23+
build:
24+
name: Build site
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Check out repo
28+
uses: actions/checkout@v4
29+
30+
- name: Set up Python
31+
uses: actions/setup-python@v5
32+
with:
33+
python-version: "3.12"
34+
35+
- name: Install MkDocs
36+
run: |
37+
python -m pip install -U pip
38+
python -m pip install \
39+
"mkdocs-material>=9.5" \
40+
"pymdown-extensions>=10"
41+
42+
- name: Build (strict)
43+
run: mkdocs build --strict
44+
45+
- name: Upload Pages artifact
46+
uses: actions/upload-pages-artifact@v3
47+
with:
48+
path: site
49+
50+
deploy:
51+
name: Deploy to GitHub Pages
52+
needs: build
53+
runs-on: ubuntu-latest
54+
environment:
55+
name: github-pages
56+
url: ${{ steps.deployment.outputs.page_url }}
57+
steps:
58+
- name: Deploy
59+
id: deployment
60+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ tools/NNS/src/*.o
2323

2424
# Stray R plotting artifact from headless regeneration
2525
Rplots.pdf
26+
27+
# MkDocs build output
28+
/site/

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
[![PyPI package](https://img.shields.io/badge/package-ovvo--nns-blue)](https://pypi.org/project/ovvo-nns/)
66
[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)
7+
[![Docs](https://img.shields.io/badge/docs-ovvo--financial.github.io-blue)](https://ovvo-financial.github.io/NNS-python/)
78
[![License](https://img.shields.io/badge/license-GPL--3.0--only-blue)](LICENSE)
89

910
`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.
@@ -178,6 +179,9 @@ uv run python examples/run_all_vignettes.py
178179

179180
## Documentation
180181

182+
The full documentation site is hosted at
183+
**<https://ovvo-financial.github.io/NNS-python/>**.
184+
181185
- [API reference manual](docs/api_reference.md)
182186
- [API status and known gaps](docs/api_status.md)
183187
- [Behavior conventions and intentional divergences](docs/conventions.md)

docs/assets/nns_hex_sticker.png

46.1 KB
Loading

docs/index.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<img src="assets/nns_hex_sticker.png" width="150" alt="NNS hex sticker" style="border: none; outline: none; margin: 0; padding: 0; display: block;">
2+
3+
[![PyPI package](https://img.shields.io/pypi/v/ovvo-nns?label=ovvo-nns&color=2780e3)](https://pypi.org/project/ovvo-nns/)
4+
[![Python](https://img.shields.io/badge/python-3.11%2B-2780e3)](https://www.python.org/)
5+
[![License](https://img.shields.io/badge/license-GPL--3.0--only-2780e3)](https://github.com/OVVO-Financial/NNS-python/blob/main/LICENSE)
6+
7+
# NNS Python
8+
9+
`ovvo-nns` brings **Nonlinear Nonparametric Statistics** to Python as the `nns`
10+
import package. It is a parity-focused port of the R `NNS` 13.0+ package,
11+
designed for real-world data that violate symmetry, linearity, or distributional
12+
assumptions.
13+
14+
NNS is built around partial moments — the lower and upper components of variance —
15+
and uses them across nonlinear dependence, correlation, causation, regression,
16+
classification, forecasting, stochastic dominance, stochastic superiority, Monte
17+
Carlo simulation, and numerical differentiation workflows.
18+
19+
!!! note "Origin"
20+
NNS was created by Fred Viole as the companion R package to Viole, F. and
21+
Nawrocki, D. (2013), *Nonlinear Nonparametric Statistics: Using Partial
22+
Moments*. **Book (2nd Edition):** <https://ovvo-financial.github.io/NNS/book/>.
23+
For a direct quantitative finance implementation of NNS, see
24+
[OVVO Labs](https://www.ovvolabs.com).
25+
26+
## Package at a glance
27+
28+
| Item | Value |
29+
|---|---|
30+
| Distribution package | `ovvo-nns` |
31+
| Import package | `nns` |
32+
| Python | `>=3.11` |
33+
| Required runtime dependencies | NumPy, SciPy |
34+
| R required at runtime | No |
35+
| Native acceleration | Private, optional `nns._nnscore` kernels where available |
36+
| Public API status | Stable, parity-focused |
37+
| License | GPL-3.0-only |
38+
39+
The public package is Python-native and does not call R at runtime. Some core
40+
kernels can use the private `_nnscore` extension when it is present, while public
41+
functions keep Python implementations and explicit fallback behavior.
42+
43+
## Get started
44+
45+
<div class="grid cards" markdown>
46+
47+
- :material-download: **[Install](install.md)**
48+
49+
`pip install ovvo-nns`, then `import nns`.
50+
51+
- :material-rocket-launch: **[Quick start](quick_start.md)**
52+
53+
Partial moments, dependence, regression, and forecasting in a few lines.
54+
55+
- :material-book-open-variant: **[API reference](api_reference.md)**
56+
57+
Function-by-function index with R `NNS` name crosswalks.
58+
59+
- :material-check-decagram: **[API status](api_status.md)**
60+
61+
Implemented, partial, guarded, and known-gap paths.
62+
63+
</div>
64+
65+
## Main API areas
66+
67+
| Area | Representative functions |
68+
|---|---|
69+
| Partial moments | `lpm`, `upm`, `lpm_ratio`, `upm_ratio`, `pm_matrix` |
70+
| Classical moment helpers | `mean_pm`, `var_pm`, `skew_pm`, `kurt_pm`, `nns_moments` |
71+
| Dependence, correlation, copula | `nns_dep`, `nns_cor`, `nns_copula` |
72+
| Causation | `nns_causation`, `causal_matrix` |
73+
| Regression and classification | `nns_reg`, `nns_m_reg`, `nns_stack`, `nns_boost` |
74+
| Forecasting | `nns_seas`, `nns_arma`, `nns_arma_optim`, `nns_var` |
75+
| Distribution tools | `nns_cdf`, `nns_anova`, `nns_norm` |
76+
| Stochastic dominance | `fsd`, `ssd`, `tsd`, `nns_sd_cluster`, `sd_efficient_set` |
77+
| Stochastic superiority and simulation | `nns_ss`, `nns_mc`, `nns_meboot` |
78+
| Differentiation | `nns_diff`, `dy_dx`, `dy_d` |
79+
| Categorical helpers | `encode_factor_codes`, `factor_2_dummy`, `factor_2_dummy_fr`, `prepare_factor_predictors` |
80+
81+
See [API status](api_status.md) for implemented, partial, guarded, and known-gap
82+
paths.
83+
84+
## Design boundaries
85+
86+
NNS Python prioritizes stable public behavior from installed R NNS 13.0+, not
87+
private helper parity. The package returns NumPy arrays and plain dictionaries
88+
rather than R `data.table` objects, uses explicit Python errors for several
89+
unsafe R coercions, and generally ignores plotting side effects.
90+
91+
See [behavior conventions](conventions.md) for detailed compatibility notes and
92+
[parity with R NNS](parity.md) for the parity target and automation.
93+
94+
## Links
95+
96+
- [View on PyPI](https://pypi.org/project/ovvo-nns/)
97+
- [Browse source code](https://github.com/OVVO-Financial/NNS-python)
98+
- [Report a bug](https://github.com/OVVO-Financial/NNS-python/issues)
99+
100+
## License
101+
102+
[GPL-3.0-only](https://www.gnu.org/licenses/gpl-3.0.en.html)
103+
104+
## Citation
105+
106+
NNS is the companion to Viole, F. and Nawrocki, D. (2013),
107+
*Nonlinear Nonparametric Statistics: Using Partial Moments* (ISBN: 1490523995).
108+
2nd edition: <https://ovvo-financial.github.io/NNS/book/>.
109+
110+
## Developers
111+
112+
- **Fred Viole** — author and maintainer
113+
- **Roberto Spadim** — contributor
114+
- **Rasheed Khoshnaw** — contributor
115+
116+
## Attribution
117+
118+
Upstream R package and reference implementation:
119+
[OVVO-Financial/NNS](https://github.com/OVVO-Financial/NNS).

docs/install.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Install
2+
3+
## From PyPI
4+
5+
```bash
6+
pip install ovvo-nns
7+
```
8+
9+
The distribution package is **`ovvo-nns`**; the import package is **`nns`**:
10+
11+
```python
12+
import nns
13+
14+
print(nns.__version__)
15+
```
16+
17+
Installing `ovvo-nns` includes the Matplotlib plotting API (`nns.plotting`).
18+
Matplotlib is a regular dependency and is imported lazily, so `import nns` stays
19+
light. See the [plot parity policy](plot_parity_policy.md) for details.
20+
21+
## Requirements
22+
23+
| Requirement | Value |
24+
|---|---|
25+
| Python | `>=3.11` (CPython 3.11, 3.12, 3.13, 3.14) |
26+
| Runtime dependencies | NumPy, SciPy, Matplotlib |
27+
| R at runtime | Not required |
28+
29+
R is used only for parity tests and local cache regeneration, never at normal
30+
runtime.
31+
32+
## Wheels vs. source builds
33+
34+
Published wheels should be preferred when available. They ship the optional
35+
private native extension (`nns._nnscore`) prebuilt for supported platforms.
36+
37+
Source builds compile the optional native extension with
38+
[`scikit-build-core`](https://scikit-build-core.readthedocs.io/) and
39+
[`nanobind`](https://nanobind.readthedocs.io/), which require a C++17 toolchain.
40+
Public APIs keep Python implementations and explicit fallback behavior, so the
41+
native extension remains a private, benchmark-backed implementation detail rather
42+
than a public API.
43+
44+
## Development install
45+
46+
```bash
47+
uv sync --group dev
48+
uv run pytest
49+
uv run ruff check .
50+
uv run mypy
51+
```
52+
53+
The default parity suite is cache-backed and does not require `Rscript`.
54+
`Rscript` and the R `NNS` package are needed only when regenerating parity caches
55+
or running live R comparison scripts.

docs/quick_start.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Quick start
2+
3+
These snippets mirror the runnable
4+
[example vignettes](https://github.com/OVVO-Financial/NNS-python/tree/main/examples/vignettes),
5+
which are exercised in CI so they stay in sync with the package.
6+
7+
## Partial moments
8+
9+
```python
10+
import numpy as np
11+
from nns import lpm, upm
12+
13+
x = np.array([-2.0, -1.0, 0.5, 3.0], dtype=np.float64)
14+
15+
lower = lpm(degree=2, target=0.0, x=x)
16+
upper = upm(degree=2, target=0.0, x=x)
17+
18+
print("lower partial moment:", lower)
19+
print("upper partial moment:", upper)
20+
```
21+
22+
## Nonlinear dependence
23+
24+
```python
25+
import numpy as np
26+
from nns import nns_cor, nns_dep
27+
28+
grid = np.linspace(-2.0, 2.0, 80, dtype=np.float64)
29+
y = grid**2
30+
31+
print("NNS dependence:", nns_dep(grid, y))
32+
print("NNS correlation:", nns_cor(grid, y))
33+
```
34+
35+
## Nonlinear regression
36+
37+
Fit a nonlinear regression and estimate new points:
38+
39+
```python
40+
import numpy as np
41+
from nns import nns_reg
42+
43+
x = np.linspace(-3.0, 3.0, 80, dtype=np.float64)
44+
y = np.sin(x) + 0.2 * x
45+
points = np.array([-1.5, 0.0, 1.5], dtype=np.float64)
46+
47+
fit = nns_reg(x, y, point_est=points, confidence_interval=None)
48+
49+
print("R2:", fit["R2"])
50+
print(np.column_stack((points, fit["Point.est"])))
51+
```
52+
53+
## Forecasting
54+
55+
Forecast a univariate series:
56+
57+
```python
58+
import numpy as np
59+
from nns import nns_arma, nns_seas
60+
61+
t = np.arange(1, 60, dtype=np.float64)
62+
series = 10.0 + np.sin(t / 3.0) + 0.05 * t
63+
64+
seasonality = nns_seas(series, modulo=[3, 4, 6], mod_only=True)
65+
forecast = nns_arma(series, h=3, seasonal_factor=4, method="lin")
66+
67+
print("best seasonal period:", seasonality["best.period"])
68+
print("forecast:", forecast)
69+
```
70+
71+
## Next steps
72+
73+
- Browse the full [API reference](api_reference.md).
74+
- Check the [API status](api_status.md) for partial, guarded, and known-gap paths.
75+
- Read the [behavior conventions](conventions.md) for intentional divergences from R.

docs/release_notes.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Release notes
2+
3+
The authoritative, per-version release history is published to:
4+
5+
- **PyPI release history:** <https://pypi.org/project/ovvo-nns/#history>
6+
- **GitHub Releases:** <https://github.com/OVVO-Financial/NNS-python/releases>
7+
8+
The currently published version is shown by the badge on the
9+
[home page](index.md) and by:
10+
11+
```python
12+
import nns
13+
14+
print(nns.__version__)
15+
```
16+
17+
## Versioning
18+
19+
`ovvo-nns` uses standard semantic-style version numbers (`MAJOR.MINOR.PATCH`).
20+
The public API is **stable and parity-focused**: documented public behavior is
21+
not expected to break across minor releases. Known partial, guarded, and
22+
known-gap paths are tracked on the [API status](api_status.md) page, and
23+
intentional divergences from R `NNS` are recorded in the
24+
[conventions](conventions.md).
25+
26+
Version numbers are kept consistent across `pyproject.toml`, the package
27+
`__version__`, and the README. This is enforced in CI by
28+
`scripts/check_version_consistency.py`.
29+
30+
For how releases are built, signed, and published, see the
31+
[release process](releasing.md).

0 commit comments

Comments
 (0)