torchvine 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- torchvine-0.1.0/LICENSE +21 -0
- torchvine-0.1.0/PKG-INFO +245 -0
- torchvine-0.1.0/README.md +211 -0
- torchvine-0.1.0/pyproject.toml +56 -0
- torchvine-0.1.0/setup.cfg +4 -0
- torchvine-0.1.0/tests/test_api_parity.py +106 -0
- torchvine-0.1.0/tests/test_basic.py +410 -0
- torchvine-0.1.0/tests/test_crosscheck_bicop.py +224 -0
- torchvine-0.1.0/tests/test_crosscheck_vinecop.py +173 -0
- torchvine-0.1.0/torchvine/__init__.py +190 -0
- torchvine-0.1.0/torchvine/bicop.py +1886 -0
- torchvine-0.1.0/torchvine/families.py +43 -0
- torchvine-0.1.0/torchvine/fit_controls.py +104 -0
- torchvine-0.1.0/torchvine/interpolation.py +183 -0
- torchvine-0.1.0/torchvine/kde1d.py +355 -0
- torchvine-0.1.0/torchvine/optimize.py +132 -0
- torchvine-0.1.0/torchvine/pair_copuladata.py +169 -0
- torchvine-0.1.0/torchvine/rvine_structure.py +377 -0
- torchvine-0.1.0/torchvine/stats.py +473 -0
- torchvine-0.1.0/torchvine/tll_fit.py +266 -0
- torchvine-0.1.0/torchvine/vine_select.py +989 -0
- torchvine-0.1.0/torchvine/vinecop.py +758 -0
- torchvine-0.1.0/torchvine.egg-info/PKG-INFO +245 -0
- torchvine-0.1.0/torchvine.egg-info/SOURCES.txt +38 -0
- torchvine-0.1.0/torchvine.egg-info/dependency_links.txt +1 -0
- torchvine-0.1.0/torchvine.egg-info/requires.txt +9 -0
- torchvine-0.1.0/torchvine.egg-info/top_level.txt +1 -0
torchvine-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016-2025 Shahab A. Shojaeezadeh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
torchvine-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: torchvine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pure-PyTorch vine copula modelling — GPU-ready, differentiable, and API-compatible with pyvinecopulib
|
|
5
|
+
Author: Bluerrror
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Bluerrror/torchvine
|
|
8
|
+
Project-URL: Repository, https://github.com/Bluerrror/torchvine
|
|
9
|
+
Project-URL: Issues, https://github.com/Bluerrror/torchvine/issues
|
|
10
|
+
Keywords: copula,vine-copula,pytorch,gpu,statistics,dependence-modeling
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: torch>=2.0
|
|
26
|
+
Requires-Dist: matplotlib>=3.5
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pyvinecopulib>=0.6; extra == "dev"
|
|
30
|
+
Requires-Dist: scipy>=1.10; extra == "dev"
|
|
31
|
+
Requires-Dist: numpy>=1.24; extra == "dev"
|
|
32
|
+
Requires-Dist: nbformat>=5.0; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# torchvine
|
|
36
|
+
|
|
37
|
+
<p align="center">
|
|
38
|
+
<img src="https://capsule-render.vercel.app/api?type=waving&height=180&color=0:ee4c2c,100:ff6f00&text=torchvine&fontColor=ffffff&fontSize=60&fontAlignY=35&desc=Pure-PyTorch%20Vine%20Copula%20Modelling&descAlign=50&descAlignY=55" width="100%" alt="torchvine"/>
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<a href="https://pypi.org/project/torchvine/"><img src="https://img.shields.io/pypi/v/torchvine?color=ee4c2c&style=for-the-badge" alt="PyPI"/></a>
|
|
43
|
+
<a href="https://pypi.org/project/torchvine/"><img src="https://img.shields.io/pypi/pyversions/torchvine?style=for-the-badge&color=ff6f00" alt="Python"/></a>
|
|
44
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="License"/></a>
|
|
45
|
+
<a href="https://pytorch.org/"><img src="https://img.shields.io/badge/PyTorch-2.0%2B-ee4c2c?style=for-the-badge&logo=pytorch&logoColor=white" alt="PyTorch"/></a>
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
GPU-ready, differentiable vine copula modelling in pure PyTorch.<br>
|
|
50
|
+
<b>Drop-in replacement</b> for <a href="https://github.com/vinecopulib/pyvinecopulib">pyvinecopulib</a> — same API, but with autograd and CUDA support.
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## ✨ Why torchvine?
|
|
56
|
+
|
|
57
|
+
| | torchvine | pyvinecopulib |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| **Backend** | Pure PyTorch (GPU / CPU) | C++ with Python bindings |
|
|
60
|
+
| **Differentiable** | ✅ Autograd-compatible | ❌ |
|
|
61
|
+
| **GPU acceleration** | ✅ CUDA tensors | ❌ CPU only |
|
|
62
|
+
| **API** | Drop-in replacement | Reference |
|
|
63
|
+
| **Copula families** | 13 (full parity) | 13 |
|
|
64
|
+
|
|
65
|
+
**Zero C/C++ dependencies** — everything is implemented in pure PyTorch, making it easy to install, debug, and extend.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 🚀 Installation
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install torchvine
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
From source:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/Bluerrror/torchvine.git
|
|
79
|
+
cd torchvine
|
|
80
|
+
pip install -e .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Requirements:** Python ≥ 3.9 | PyTorch ≥ 2.0 | matplotlib ≥ 3.5
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 📖 Quick Start
|
|
88
|
+
|
|
89
|
+
### Bivariate Copula
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
import torch
|
|
93
|
+
import torchvine as tv
|
|
94
|
+
|
|
95
|
+
# Create a Gaussian copula with correlation 0.7
|
|
96
|
+
cop = tv.Bicop(tv.BicopFamily.gaussian, parameters=torch.tensor([0.7]))
|
|
97
|
+
print(cop.str()) # <Bicop> family=gaussian, rotation=0, parameters=[0.7]
|
|
98
|
+
print(cop.parameters_to_tau()) # Kendall's tau ≈ 0.494
|
|
99
|
+
|
|
100
|
+
# Evaluate density and simulate
|
|
101
|
+
u = torch.rand(1000, 2, dtype=torch.float64)
|
|
102
|
+
pdf_vals = cop.pdf(u)
|
|
103
|
+
samples = cop.simulate(1000)
|
|
104
|
+
|
|
105
|
+
# Fit from data (automatic family selection)
|
|
106
|
+
fitted = tv.Bicop()
|
|
107
|
+
fitted.select(samples)
|
|
108
|
+
print(fitted.str())
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Vine Copula
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
# Fit a 5-dimensional vine copula
|
|
115
|
+
data = torch.rand(500, 5, dtype=torch.float64)
|
|
116
|
+
vine = tv.Vinecop(d=5)
|
|
117
|
+
vine.select(data, controls=tv.FitControlsVinecop(family_set=tv.parametric))
|
|
118
|
+
|
|
119
|
+
print(vine.str())
|
|
120
|
+
print(f"Log-likelihood: {vine.loglik(data):.2f}")
|
|
121
|
+
print(f"AIC: {vine.aic(data):.2f}")
|
|
122
|
+
|
|
123
|
+
# Simulate and transform
|
|
124
|
+
sim = vine.simulate(1000)
|
|
125
|
+
pit = vine.rosenblatt(data) # probability integral transform
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Dependence Measures
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
x = torch.randn(1000, dtype=torch.float64)
|
|
132
|
+
y = 0.6 * x + 0.8 * torch.randn(1000, dtype=torch.float64)
|
|
133
|
+
|
|
134
|
+
print(tv.kendall_tau(x, y)) # Kendall's tau
|
|
135
|
+
print(tv.spearman_rho(x, y)) # Spearman's rho
|
|
136
|
+
print(tv.pearson_cor(x, y)) # Pearson correlation
|
|
137
|
+
print(tv.blomqvist_beta(x, y)) # Blomqvist's beta
|
|
138
|
+
print(tv.hoeffding_d(x, y)) # Hoeffding's D
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### GPU Acceleration
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
145
|
+
u_gpu = torch.rand(10000, 2, dtype=torch.float64, device=device)
|
|
146
|
+
|
|
147
|
+
cop = tv.Bicop(tv.BicopFamily.clayton, parameters=torch.tensor([3.0], device=device))
|
|
148
|
+
pdf_gpu = cop.pdf(u_gpu) # runs entirely on GPU
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 📋 Supported Copula Families
|
|
154
|
+
|
|
155
|
+
| Family | Parameters | Type |
|
|
156
|
+
|--------|-----------|------|
|
|
157
|
+
| Independence | 0 | — |
|
|
158
|
+
| Gaussian | 1 (ρ) | Elliptical |
|
|
159
|
+
| Student-t | 2 (ρ, ν) | Elliptical |
|
|
160
|
+
| Clayton | 1 (θ) | Archimedean |
|
|
161
|
+
| Gumbel | 1 (θ) | Archimedean / Extreme-value |
|
|
162
|
+
| Frank | 1 (θ) | Archimedean |
|
|
163
|
+
| Joe | 1 (θ) | Archimedean |
|
|
164
|
+
| BB1 | 2 (θ, δ) | Archimedean |
|
|
165
|
+
| BB6 | 2 (θ, δ) | Archimedean |
|
|
166
|
+
| BB7 | 2 (θ, δ) | Archimedean |
|
|
167
|
+
| BB8 | 2 (θ, δ) | Archimedean |
|
|
168
|
+
| Tawn | 3 (ψ₁, ψ₂, θ) | Extreme-value |
|
|
169
|
+
| TLL | nonparametric | Kernel-based |
|
|
170
|
+
|
|
171
|
+
All asymmetric families support rotations (0°, 90°, 180°, 270°).
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 📚 API Reference
|
|
176
|
+
|
|
177
|
+
### Core Classes
|
|
178
|
+
|
|
179
|
+
| Class | Description |
|
|
180
|
+
|-------|-------------|
|
|
181
|
+
| `tv.Bicop` | Bivariate copula — create, fit, evaluate, simulate |
|
|
182
|
+
| `tv.Vinecop` | Vine copula model — select, pdf, simulate, rosenblatt |
|
|
183
|
+
| `tv.Kde1d` | 1-D kernel density estimation — fit, pdf, cdf, quantile |
|
|
184
|
+
| `tv.RVineStructure` | R-vine structure matrix |
|
|
185
|
+
| `tv.DVineStructure` | D-vine structure (convenience subclass) |
|
|
186
|
+
| `tv.CVineStructure` | C-vine structure (convenience subclass) |
|
|
187
|
+
| `tv.FitControlsBicop` | Fitting options for bivariate copulas |
|
|
188
|
+
| `tv.FitControlsVinecop` | Fitting options for vine copulas |
|
|
189
|
+
| `tv.BicopFamily` | Enum of all copula families |
|
|
190
|
+
|
|
191
|
+
### Dependence Measures
|
|
192
|
+
|
|
193
|
+
| Function | Description |
|
|
194
|
+
|----------|-------------|
|
|
195
|
+
| `tv.kendall_tau(x, y)` | Kendall's rank correlation |
|
|
196
|
+
| `tv.spearman_rho(x, y)` | Spearman's rank correlation |
|
|
197
|
+
| `tv.pearson_cor(x, y)` | Pearson linear correlation |
|
|
198
|
+
| `tv.blomqvist_beta(x, y)` | Blomqvist's beta (medial correlation) |
|
|
199
|
+
| `tv.hoeffding_d(x, y)` | Hoeffding's D statistic |
|
|
200
|
+
| `tv.wdm(x, y, method)` | Unified interface for all measures |
|
|
201
|
+
|
|
202
|
+
### Utilities
|
|
203
|
+
|
|
204
|
+
| Function | Description |
|
|
205
|
+
|----------|-------------|
|
|
206
|
+
| `tv.to_pseudo_obs(data)` | Rank-transform to pseudo-observations |
|
|
207
|
+
| `tv.simulate_uniform(n, d)` | Uniform random / quasi-random samples |
|
|
208
|
+
| `tv.pairs_copula_data(data)` | Pairs plot with copula density contours |
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 📓 Examples
|
|
213
|
+
|
|
214
|
+
See the [`examples/`](examples/) directory for Jupyter notebooks:
|
|
215
|
+
|
|
216
|
+
| Notebook | Topics |
|
|
217
|
+
|----------|--------|
|
|
218
|
+
| [01 — Getting Started](examples/01_getting_started.ipynb) | Imports, copula basics, simulation, fitting |
|
|
219
|
+
| [02 — Bivariate Copulas](examples/02_bivariate_copulas.ipynb) | All families, rotations, Student-t, model selection |
|
|
220
|
+
| [03 — Vine Copulas](examples/03_vine_copulas.ipynb) | Vine fitting, structure, simulation, Rosenblatt transform |
|
|
221
|
+
| [04 — Kde1d & Statistics](examples/04_kde1d_and_stats.ipynb) | KDE, dependence measures, pairs plot visualization |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 🤝 Contributing
|
|
226
|
+
|
|
227
|
+
1. Fork the repo
|
|
228
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
229
|
+
3. Commit changes: `git commit -m "Add amazing feature"`
|
|
230
|
+
4. Push: `git push origin feature/amazing-feature`
|
|
231
|
+
5. Open a Pull Request
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 📄 License
|
|
236
|
+
|
|
237
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 🙏 Acknowledgements
|
|
242
|
+
|
|
243
|
+
- API design follows [vinecopulib](https://github.com/vinecopulib/vinecopulib) / [pyvinecopulib](https://github.com/vinecopulib/pyvinecopulib) by Thomas Nagler and Thibault Vatter.
|
|
244
|
+
|
|
245
|
+
<img width="100%" src="https://capsule-render.vercel.app/api?type=waving&color=0:ee4c2c,100:ff6f00&height=100§ion=footer"/>
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# torchvine
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://capsule-render.vercel.app/api?type=waving&height=180&color=0:ee4c2c,100:ff6f00&text=torchvine&fontColor=ffffff&fontSize=60&fontAlignY=35&desc=Pure-PyTorch%20Vine%20Copula%20Modelling&descAlign=50&descAlignY=55" width="100%" alt="torchvine"/>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://pypi.org/project/torchvine/"><img src="https://img.shields.io/pypi/v/torchvine?color=ee4c2c&style=for-the-badge" alt="PyPI"/></a>
|
|
9
|
+
<a href="https://pypi.org/project/torchvine/"><img src="https://img.shields.io/pypi/pyversions/torchvine?style=for-the-badge&color=ff6f00" alt="Python"/></a>
|
|
10
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="License"/></a>
|
|
11
|
+
<a href="https://pytorch.org/"><img src="https://img.shields.io/badge/PyTorch-2.0%2B-ee4c2c?style=for-the-badge&logo=pytorch&logoColor=white" alt="PyTorch"/></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
GPU-ready, differentiable vine copula modelling in pure PyTorch.<br>
|
|
16
|
+
<b>Drop-in replacement</b> for <a href="https://github.com/vinecopulib/pyvinecopulib">pyvinecopulib</a> — same API, but with autograd and CUDA support.
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## ✨ Why torchvine?
|
|
22
|
+
|
|
23
|
+
| | torchvine | pyvinecopulib |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| **Backend** | Pure PyTorch (GPU / CPU) | C++ with Python bindings |
|
|
26
|
+
| **Differentiable** | ✅ Autograd-compatible | ❌ |
|
|
27
|
+
| **GPU acceleration** | ✅ CUDA tensors | ❌ CPU only |
|
|
28
|
+
| **API** | Drop-in replacement | Reference |
|
|
29
|
+
| **Copula families** | 13 (full parity) | 13 |
|
|
30
|
+
|
|
31
|
+
**Zero C/C++ dependencies** — everything is implemented in pure PyTorch, making it easy to install, debug, and extend.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🚀 Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install torchvine
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
From source:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/Bluerrror/torchvine.git
|
|
45
|
+
cd torchvine
|
|
46
|
+
pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Requirements:** Python ≥ 3.9 | PyTorch ≥ 2.0 | matplotlib ≥ 3.5
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 📖 Quick Start
|
|
54
|
+
|
|
55
|
+
### Bivariate Copula
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import torch
|
|
59
|
+
import torchvine as tv
|
|
60
|
+
|
|
61
|
+
# Create a Gaussian copula with correlation 0.7
|
|
62
|
+
cop = tv.Bicop(tv.BicopFamily.gaussian, parameters=torch.tensor([0.7]))
|
|
63
|
+
print(cop.str()) # <Bicop> family=gaussian, rotation=0, parameters=[0.7]
|
|
64
|
+
print(cop.parameters_to_tau()) # Kendall's tau ≈ 0.494
|
|
65
|
+
|
|
66
|
+
# Evaluate density and simulate
|
|
67
|
+
u = torch.rand(1000, 2, dtype=torch.float64)
|
|
68
|
+
pdf_vals = cop.pdf(u)
|
|
69
|
+
samples = cop.simulate(1000)
|
|
70
|
+
|
|
71
|
+
# Fit from data (automatic family selection)
|
|
72
|
+
fitted = tv.Bicop()
|
|
73
|
+
fitted.select(samples)
|
|
74
|
+
print(fitted.str())
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Vine Copula
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
# Fit a 5-dimensional vine copula
|
|
81
|
+
data = torch.rand(500, 5, dtype=torch.float64)
|
|
82
|
+
vine = tv.Vinecop(d=5)
|
|
83
|
+
vine.select(data, controls=tv.FitControlsVinecop(family_set=tv.parametric))
|
|
84
|
+
|
|
85
|
+
print(vine.str())
|
|
86
|
+
print(f"Log-likelihood: {vine.loglik(data):.2f}")
|
|
87
|
+
print(f"AIC: {vine.aic(data):.2f}")
|
|
88
|
+
|
|
89
|
+
# Simulate and transform
|
|
90
|
+
sim = vine.simulate(1000)
|
|
91
|
+
pit = vine.rosenblatt(data) # probability integral transform
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Dependence Measures
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
x = torch.randn(1000, dtype=torch.float64)
|
|
98
|
+
y = 0.6 * x + 0.8 * torch.randn(1000, dtype=torch.float64)
|
|
99
|
+
|
|
100
|
+
print(tv.kendall_tau(x, y)) # Kendall's tau
|
|
101
|
+
print(tv.spearman_rho(x, y)) # Spearman's rho
|
|
102
|
+
print(tv.pearson_cor(x, y)) # Pearson correlation
|
|
103
|
+
print(tv.blomqvist_beta(x, y)) # Blomqvist's beta
|
|
104
|
+
print(tv.hoeffding_d(x, y)) # Hoeffding's D
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### GPU Acceleration
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
111
|
+
u_gpu = torch.rand(10000, 2, dtype=torch.float64, device=device)
|
|
112
|
+
|
|
113
|
+
cop = tv.Bicop(tv.BicopFamily.clayton, parameters=torch.tensor([3.0], device=device))
|
|
114
|
+
pdf_gpu = cop.pdf(u_gpu) # runs entirely on GPU
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 📋 Supported Copula Families
|
|
120
|
+
|
|
121
|
+
| Family | Parameters | Type |
|
|
122
|
+
|--------|-----------|------|
|
|
123
|
+
| Independence | 0 | — |
|
|
124
|
+
| Gaussian | 1 (ρ) | Elliptical |
|
|
125
|
+
| Student-t | 2 (ρ, ν) | Elliptical |
|
|
126
|
+
| Clayton | 1 (θ) | Archimedean |
|
|
127
|
+
| Gumbel | 1 (θ) | Archimedean / Extreme-value |
|
|
128
|
+
| Frank | 1 (θ) | Archimedean |
|
|
129
|
+
| Joe | 1 (θ) | Archimedean |
|
|
130
|
+
| BB1 | 2 (θ, δ) | Archimedean |
|
|
131
|
+
| BB6 | 2 (θ, δ) | Archimedean |
|
|
132
|
+
| BB7 | 2 (θ, δ) | Archimedean |
|
|
133
|
+
| BB8 | 2 (θ, δ) | Archimedean |
|
|
134
|
+
| Tawn | 3 (ψ₁, ψ₂, θ) | Extreme-value |
|
|
135
|
+
| TLL | nonparametric | Kernel-based |
|
|
136
|
+
|
|
137
|
+
All asymmetric families support rotations (0°, 90°, 180°, 270°).
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 📚 API Reference
|
|
142
|
+
|
|
143
|
+
### Core Classes
|
|
144
|
+
|
|
145
|
+
| Class | Description |
|
|
146
|
+
|-------|-------------|
|
|
147
|
+
| `tv.Bicop` | Bivariate copula — create, fit, evaluate, simulate |
|
|
148
|
+
| `tv.Vinecop` | Vine copula model — select, pdf, simulate, rosenblatt |
|
|
149
|
+
| `tv.Kde1d` | 1-D kernel density estimation — fit, pdf, cdf, quantile |
|
|
150
|
+
| `tv.RVineStructure` | R-vine structure matrix |
|
|
151
|
+
| `tv.DVineStructure` | D-vine structure (convenience subclass) |
|
|
152
|
+
| `tv.CVineStructure` | C-vine structure (convenience subclass) |
|
|
153
|
+
| `tv.FitControlsBicop` | Fitting options for bivariate copulas |
|
|
154
|
+
| `tv.FitControlsVinecop` | Fitting options for vine copulas |
|
|
155
|
+
| `tv.BicopFamily` | Enum of all copula families |
|
|
156
|
+
|
|
157
|
+
### Dependence Measures
|
|
158
|
+
|
|
159
|
+
| Function | Description |
|
|
160
|
+
|----------|-------------|
|
|
161
|
+
| `tv.kendall_tau(x, y)` | Kendall's rank correlation |
|
|
162
|
+
| `tv.spearman_rho(x, y)` | Spearman's rank correlation |
|
|
163
|
+
| `tv.pearson_cor(x, y)` | Pearson linear correlation |
|
|
164
|
+
| `tv.blomqvist_beta(x, y)` | Blomqvist's beta (medial correlation) |
|
|
165
|
+
| `tv.hoeffding_d(x, y)` | Hoeffding's D statistic |
|
|
166
|
+
| `tv.wdm(x, y, method)` | Unified interface for all measures |
|
|
167
|
+
|
|
168
|
+
### Utilities
|
|
169
|
+
|
|
170
|
+
| Function | Description |
|
|
171
|
+
|----------|-------------|
|
|
172
|
+
| `tv.to_pseudo_obs(data)` | Rank-transform to pseudo-observations |
|
|
173
|
+
| `tv.simulate_uniform(n, d)` | Uniform random / quasi-random samples |
|
|
174
|
+
| `tv.pairs_copula_data(data)` | Pairs plot with copula density contours |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 📓 Examples
|
|
179
|
+
|
|
180
|
+
See the [`examples/`](examples/) directory for Jupyter notebooks:
|
|
181
|
+
|
|
182
|
+
| Notebook | Topics |
|
|
183
|
+
|----------|--------|
|
|
184
|
+
| [01 — Getting Started](examples/01_getting_started.ipynb) | Imports, copula basics, simulation, fitting |
|
|
185
|
+
| [02 — Bivariate Copulas](examples/02_bivariate_copulas.ipynb) | All families, rotations, Student-t, model selection |
|
|
186
|
+
| [03 — Vine Copulas](examples/03_vine_copulas.ipynb) | Vine fitting, structure, simulation, Rosenblatt transform |
|
|
187
|
+
| [04 — Kde1d & Statistics](examples/04_kde1d_and_stats.ipynb) | KDE, dependence measures, pairs plot visualization |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 🤝 Contributing
|
|
192
|
+
|
|
193
|
+
1. Fork the repo
|
|
194
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
195
|
+
3. Commit changes: `git commit -m "Add amazing feature"`
|
|
196
|
+
4. Push: `git push origin feature/amazing-feature`
|
|
197
|
+
5. Open a Pull Request
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 📄 License
|
|
202
|
+
|
|
203
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 🙏 Acknowledgements
|
|
208
|
+
|
|
209
|
+
- API design follows [vinecopulib](https://github.com/vinecopulib/vinecopulib) / [pyvinecopulib](https://github.com/vinecopulib/pyvinecopulib) by Thomas Nagler and Thibault Vatter.
|
|
210
|
+
|
|
211
|
+
<img width="100%" src="https://capsule-render.vercel.app/api?type=waving&color=0:ee4c2c,100:ff6f00&height=100§ion=footer"/>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "torchvine"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Pure-PyTorch vine copula modelling — GPU-ready, differentiable, and API-compatible with pyvinecopulib"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
keywords = ["copula", "vine-copula", "pytorch", "gpu", "statistics", "dependence-modeling"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Bluerrror" },
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Programming Language :: Python :: 3.9",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
27
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"torch>=2.0",
|
|
31
|
+
"matplotlib>=3.5",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = [
|
|
36
|
+
"pytest>=7.0",
|
|
37
|
+
"pyvinecopulib>=0.6",
|
|
38
|
+
"scipy>=1.10",
|
|
39
|
+
"numpy>=1.24",
|
|
40
|
+
"nbformat>=5.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://github.com/Bluerrror/torchvine"
|
|
45
|
+
Repository = "https://github.com/Bluerrror/torchvine"
|
|
46
|
+
Issues = "https://github.com/Bluerrror/torchvine/issues"
|
|
47
|
+
|
|
48
|
+
[tool.setuptools]
|
|
49
|
+
package-dir = { "" = "." }
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
where = ["."]
|
|
53
|
+
include = ["torchvine*"]
|
|
54
|
+
|
|
55
|
+
[tool.pytest.ini_options]
|
|
56
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Test that torchvine has API parity with pyvinecopulib (excluding student copula)."""
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
import pyvinecopulib as pv
|
|
6
|
+
HAS_PV = True
|
|
7
|
+
except ImportError:
|
|
8
|
+
HAS_PV = False
|
|
9
|
+
|
|
10
|
+
import torchvine as tv
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@unittest.skipUnless(HAS_PV, "pyvinecopulib not installed")
|
|
14
|
+
class TestBicopAPIParity(unittest.TestCase):
|
|
15
|
+
"""Every public method on pv.Bicop should exist on tv.Bicop."""
|
|
16
|
+
|
|
17
|
+
SKIP = {"plot"} # plot may differ in implementation
|
|
18
|
+
|
|
19
|
+
def test_all_methods_exist(self):
|
|
20
|
+
pv_methods = {m for m in dir(pv.Bicop) if not m.startswith("_")} - self.SKIP
|
|
21
|
+
tv_methods = {m for m in dir(tv.Bicop) if not m.startswith("_")}
|
|
22
|
+
missing = pv_methods - tv_methods
|
|
23
|
+
self.assertEqual(missing, set(),
|
|
24
|
+
f"Missing Bicop methods: {missing}")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@unittest.skipUnless(HAS_PV, "pyvinecopulib not installed")
|
|
28
|
+
class TestVinecopAPIParity(unittest.TestCase):
|
|
29
|
+
"""Every public method on pv.Vinecop should exist on tv.Vinecop."""
|
|
30
|
+
|
|
31
|
+
SKIP = {"plot"}
|
|
32
|
+
|
|
33
|
+
def test_all_methods_exist(self):
|
|
34
|
+
pv_methods = {m for m in dir(pv.Vinecop) if not m.startswith("_")} - self.SKIP
|
|
35
|
+
tv_inst = tv.Vinecop.from_dimension(3)
|
|
36
|
+
tv_methods = {m for m in dir(tv_inst) if not m.startswith("_")}
|
|
37
|
+
missing = pv_methods - tv_methods
|
|
38
|
+
self.assertEqual(missing, set(),
|
|
39
|
+
f"Missing Vinecop methods: {missing}")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@unittest.skipUnless(HAS_PV, "pyvinecopulib not installed")
|
|
43
|
+
class TestRVineStructureAPIParity(unittest.TestCase):
|
|
44
|
+
"""Every public method on pv.RVineStructure should exist on tv.RVineStructure."""
|
|
45
|
+
|
|
46
|
+
def test_all_methods_exist(self):
|
|
47
|
+
pv_methods = {m for m in dir(pv.RVineStructure) if not m.startswith("_")}
|
|
48
|
+
tv_inst = tv.RVineStructure.from_dimension(4)
|
|
49
|
+
tv_methods = {m for m in dir(tv_inst) if not m.startswith("_")}
|
|
50
|
+
missing = pv_methods - tv_methods
|
|
51
|
+
self.assertEqual(missing, set(),
|
|
52
|
+
f"Missing RVineStructure methods: {missing}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@unittest.skipUnless(HAS_PV, "pyvinecopulib not installed")
|
|
56
|
+
class TestFitControlsAPIParity(unittest.TestCase):
|
|
57
|
+
"""FitControls classes should have matching attributes."""
|
|
58
|
+
|
|
59
|
+
SKIP_BICOP = set()
|
|
60
|
+
SKIP_VINECOP = set()
|
|
61
|
+
|
|
62
|
+
def test_bicop_controls(self):
|
|
63
|
+
pv_attrs = {m for m in dir(pv.FitControlsBicop) if not m.startswith("_")} - self.SKIP_BICOP
|
|
64
|
+
tv_inst = tv.FitControlsBicop()
|
|
65
|
+
tv_attrs = {m for m in dir(tv_inst) if not m.startswith("_")}
|
|
66
|
+
missing = pv_attrs - tv_attrs
|
|
67
|
+
self.assertEqual(missing, set(),
|
|
68
|
+
f"Missing FitControlsBicop attrs: {missing}")
|
|
69
|
+
|
|
70
|
+
def test_vinecop_controls(self):
|
|
71
|
+
pv_attrs = {m for m in dir(pv.FitControlsVinecop) if not m.startswith("_")} - self.SKIP_VINECOP
|
|
72
|
+
tv_inst = tv.FitControlsVinecop()
|
|
73
|
+
tv_attrs = {m for m in dir(tv_inst) if not m.startswith("_")}
|
|
74
|
+
missing = pv_attrs - tv_attrs
|
|
75
|
+
self.assertEqual(missing, set(),
|
|
76
|
+
f"Missing FitControlsVinecop attrs: {missing}")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@unittest.skipUnless(HAS_PV, "pyvinecopulib not installed")
|
|
80
|
+
class TestModuleLevelParity(unittest.TestCase):
|
|
81
|
+
"""Module-level names should exist in torchvine."""
|
|
82
|
+
|
|
83
|
+
# Names that are intentionally excluded
|
|
84
|
+
SKIP = {"student", "benchmark", "pyvinecopulib_ext"}
|
|
85
|
+
|
|
86
|
+
def test_module_names(self):
|
|
87
|
+
pv_names = {m for m in dir(pv)
|
|
88
|
+
if not m.startswith("_") and m[0].islower()} - self.SKIP
|
|
89
|
+
tv_names = {m for m in dir(tv) if not m.startswith("_") and m[0].islower()}
|
|
90
|
+
missing = pv_names - tv_names
|
|
91
|
+
self.assertEqual(missing, set(),
|
|
92
|
+
f"Missing module-level names: {missing}")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@unittest.skipUnless(HAS_PV, "pyvinecopulib not installed")
|
|
96
|
+
class TestFamilyEnumParity(unittest.TestCase):
|
|
97
|
+
"""BicopFamily enum should contain all pyvinecopulib families except student."""
|
|
98
|
+
|
|
99
|
+
def test_families_match(self):
|
|
100
|
+
pv_fams = {f.name for f in pv.BicopFamily} - {"student"}
|
|
101
|
+
tv_fams = {f.name for f in tv.BicopFamily}
|
|
102
|
+
self.assertEqual(pv_fams, tv_fams)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
if __name__ == "__main__":
|
|
106
|
+
unittest.main()
|