use stochastic_rs_core::simd_rng::SeedExt;
use stochastic_rs_distributions::traits::FloatExt;
use stochastic_rs_stats::hurst::HurstResult;
use stochastic_rs_stochastic::device::Cpu;
use stochastic_rs_stochastic::noise::fgn::Fgn;
use stochastic_rs_stochastic::process::fbm::Fbm;
pub fn fgn_from_hurst_result<T: FloatExt, S: SeedExt>(
result: &HurstResult<T>,
n: usize,
t: Option<T>,
seed: S,
) -> Fgn<T, S, Cpu> {
Fgn::new(result.hurst, n, t, seed)
}
pub fn fbm_from_hurst_result<T: FloatExt, S: SeedExt>(
result: &HurstResult<T>,
n: usize,
t: Option<T>,
seed: S,
) -> Fbm<T, S, Cpu> {
Fbm::new(result.hurst, n, t, seed)
}
#[cfg(test)]
mod tests {
use stochastic_rs_core::simd_rng::Deterministic;
use stochastic_rs_stats::hurst::HurstEstimator;
use stochastic_rs_stats::hurst::rs::RescaledRange;
use stochastic_rs_stochastic::traits::ProcessExt;
use super::*;
#[test]
fn fgn_from_hurst_result_round_trips_through_rescaled_range() {
let true_h = 0.3;
let path = Fgn::<f64, _, Cpu>::new(true_h, 4096, Some(1.0), Deterministic::new(42)).sample();
let estimator = RescaledRange {
take_differences: false,
..RescaledRange::default()
};
let result = estimator.estimate(path.view()).unwrap();
assert!(
(result.hurst - true_h).abs() < 0.1,
"estimate H = {:.3} (true = {:.3})",
result.hurst,
true_h
);
let rebuilt = fgn_from_hurst_result(&result, 4096, Some(1.0), Deterministic::new(7));
assert_eq!(rebuilt.hurst, result.hurst);
let resampled = rebuilt.sample();
let reestimated = estimator.estimate(resampled.view()).unwrap();
assert!(
(reestimated.hurst - true_h).abs() < 0.15,
"re-estimated H = {:.3} (true = {:.3})",
reestimated.hurst,
true_h
);
}
#[test]
fn fbm_from_hurst_result_wires_fields_and_samples() {
let estimator = RescaledRange {
take_differences: false,
..RescaledRange::default()
};
let path = Fgn::<f64, _, Cpu>::new(0.6, 2048, Some(1.0), Deterministic::new(3)).sample();
let result = estimator.estimate(path.view()).unwrap();
let fbm = fbm_from_hurst_result(&result, 512, Some(2.0), Deterministic::new(9));
assert_eq!(fbm.hurst, result.hurst);
assert_eq!(fbm.n, 512);
assert_eq!(fbm.t, Some(2.0));
let sample = fbm.sample();
assert_eq!(sample.len(), 512);
assert!(sample.iter().all(|v| v.is_finite()));
}
}