1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! Core copula modeling for validated pseudo-observations.
//!
//! `rscopulas` is the main Rust surface for fitting, evaluating, and
//! sampling:
//!
//! - single-family copulas such as Gaussian, Student t, Clayton, Frank, and
//! Gumbel-Hougaard,
//! - low-level pair-copula kernels with h-functions and inverse h-functions,
//! including **Khoudraji** asymmetric pair copulas,
//! - C-vine, D-vine, and R-vine copulas.
//!
//! The crate assumes your data is already in pseudo-observation form: finite
//! values strictly inside `(0, 1)`. If you start from raw observations, estimate
//! or transform the marginals first, then build a [`PseudoObs`] matrix.
//!
//! # Quick start
//!
//! ```no_run
//! use ndarray::array;
//! use rand::{rngs::StdRng, SeedableRng};
//! use rscopulas::{CopulaModel, FitOptions, GaussianCopula, PseudoObs};
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let data = PseudoObs::new(array![
//! [0.12, 0.18],
//! [0.21, 0.25],
//! [0.27, 0.22],
//! [0.35, 0.42],
//! [0.48, 0.51],
//! [0.56, 0.49],
//! [0.68, 0.73],
//! [0.82, 0.79],
//! ])?;
//!
//! let fit = GaussianCopula::fit(&data, &FitOptions::default())?;
//! println!("AIC: {}", fit.diagnostics.aic);
//!
//! let log_pdf = fit.model.log_pdf(&data, &Default::default())?;
//! println!("first log density = {}", log_pdf[0]);
//!
//! let mut rng = StdRng::seed_from_u64(7);
//! let sample = fit.model.sample(4, &mut rng, &Default::default())?;
//! println!("sample = {:?}", sample);
//! # Ok(())
//! # }
//! ```
//!
//! # Fit a vine copula
//!
//! ```no_run
//! use ndarray::array;
//! use rscopulas::{
//! PairCopulaFamily, PseudoObs, SelectionCriterion, VineCopula, VineFitOptions,
//! };
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let data = PseudoObs::new(array![
//! [0.12, 0.18, 0.21],
//! [0.21, 0.25, 0.29],
//! [0.27, 0.22, 0.31],
//! [0.35, 0.42, 0.39],
//! [0.48, 0.51, 0.46],
//! [0.56, 0.49, 0.58],
//! [0.68, 0.73, 0.69],
//! [0.82, 0.79, 0.76],
//! ])?;
//!
//! let options = VineFitOptions {
//! family_set: vec![
//! PairCopulaFamily::Independence,
//! PairCopulaFamily::Gaussian,
//! PairCopulaFamily::Clayton,
//! PairCopulaFamily::Frank,
//! PairCopulaFamily::Gumbel,
//! PairCopulaFamily::Khoudraji,
//! ],
//! include_rotations: true,
//! criterion: SelectionCriterion::Aic,
//! truncation_level: Some(1),
//! ..VineFitOptions::default()
//! };
//!
//! let fit = VineCopula::fit_r_vine(&data, &options)?;
//! println!("structure = {:?}", fit.model.structure());
//! println!("order = {:?}", fit.model.order());
//! # Ok(())
//! # }
//! ```
//!
//! # Backend expectations
//!
//! The crate exposes explicit execution policy controls through [`ExecPolicy`]
//! and [`Device`]. Today, `Auto` is conservative and does not promise that
//! every numerically heavy path uses CUDA or Metal. If you need a deterministic
//! backend choice, prefer `ExecPolicy::Force(...)`.
//!
pub use PseudoObs;
pub use ;
pub use ;
pub use ;