<commit_before>//! Fractional Brownian motion and fractional Gaussian noise.

use complex::Complex;
use probability::distribution::{Distribution, Gaussian};
use probability::generator::Generator;

use {Process, Stationary};
use gaussian::circulant_embedding;

macro_rules! hurst(
    ($value:expr) => ({
        let value = $value;
        debug_assert!(value > 0.0 && value < 1.0);
        value
    });
);

macro_rules! step(
    ($value:expr) => ({
        let value = $value;
        debug_assert!(value > 0.0);
        value
    });
);

/// A fractional Brownian motion.
pub struct Motion {
    hurst: f64,
}

/// A fractional Gaussian noise.
pub struct Noise {
    hurst: f64,
    step: f64,
}

impl Motion {
    /// Create a fractional Brownian motion.
    #[inline]
    pub fn new(hurst: f64) -> Motion {
        Motion { hurst: hurst!(hurst) }
    }

    /// Generate a sample path.
    pub fn sample<G>(&self, points: usize, step: f64, generator: &mut G) -> Vec<f64>
        where G: Generator
    {
        match points {
            0 => vec![],
            1 => vec![0.0],
            _ => {
                let mut data = vec![0.0];
                data.extend(Noise::new(self.hurst, step).sample(points - 1, generator));
                for i in 2..points {
                    data[i] += data[i - 1];
                }
                data
            },
        }
    }
}

impl Noise {
    /// Create a fractional Gaussian noise.
    #[inline]
    pub fn new(hurst: f64, step: f64) -> Noise {
        Noise { hurst: hurst!(hurst), step: step!(step) }
    }

    /// Generate a sample path.
    pub fn sample<G>(&self, points: usize, generator: &mut G) -> Vec<f64>
        where G: Generator
    {
        match points {
            0 => vec![],
            1 => vec![Gaussian::new(0.0, Stationary::var(self).sqrt()).sample(generator)],
            _ => {
                let n = points - 1;
                let gaussian = Gaussian::new(0.0, 1.0);
                let data = circulant_embedding(self, n, || gaussian.sample(generator));
                data.iter().take(points).map(|point| point.re()).collect()
            },
        }
    }
}

impl Process for Motion {
    type Index = f64;
    type State = f64;

    fn cov(&self, t: f64, s: f64) -> f64 {
        debug_assert!(t >= 0.0 && s >= 0.0);
        let power = 2.0 * self.hurst;
        0.5 * (t.powf(power) + s.powf(power) - (t - s).abs().powf(power))
    }<commit_msg>Update the usage of probability<commit_after>//! Fractional Brownian motion and fractional Gaussian noise.

use complex::Complex;
use probability::distribution::{Distribution, Gaussian};
use probability::prelude::Source;

use {Process, Stationary};
use gaussian::circulant_embedding;

macro_rules! hurst(
    ($value:expr) => ({
        let value = $value;
        debug_assert!(value > 0.0 && value < 1.0);
        value
    });
);

macro_rules! step(
    ($value:expr) => ({
        let value = $value;
        debug_assert!(value > 0.0);
        value
    });
);

/// A fractional Brownian motion.
pub struct Motion {
    hurst: f64,
}

/// A fractional Gaussian noise.
pub struct Noise {
    hurst: f64,
    step: f64,
}

impl Motion {
    /// Create a fractional Brownian motion.
    #[inline]
    pub fn new(hurst: f64) -> Motion {
        Motion { hurst: hurst!(hurst) }
    }

    /// Generate a sample path.
    pub fn sample<S>(&self, points: usize, step: f64, source: &mut S) -> Vec<f64>
        where S: Source
    {
        match points {
            0 => vec![],
            1 => vec![0.0],
            _ => {
                let mut data = vec![0.0];
                data.extend(Noise::new(self.hurst, step).sample(points - 1, source));
                for i in 2..points {
                    data[i] += data[i - 1];
                }
                data
            },
        }
    }
}

impl Noise {
    /// Create a fractional Gaussian noise.
    #[inline]
    pub fn new(hurst: f64, step: f64) -> Noise {
        Noise { hurst: hurst!(hurst), step: step!(step) }
    }

    /// Generate a sample path.
    pub fn sample<S>(&self, points: usize, source: &mut S) -> Vec<f64>
        where S: Source
    {
        match points {
            0 => vec![],
            1 => vec![Gaussian::new(0.0, Stationary::var(self).sqrt()).sample(source)],
            _ => {
                let n = points - 1;
                let gaussian = Gaussian::new(0.0, 1.0);
                let data = circulant_embedding(self, n, || gaussian.sample(source));
                data.iter().take(points).map(|point| point.re()).collect()
            },
        }
    }
}

impl Process for Motion {
    type Index = f64;
    type State = f64;

    fn cov(&self, t: f64, s: f64) -> f64 {
        debug_assert!(t >= 0.0 && s >= 0.0);
        let power = 2.0 * self.hurst;
        0.5 * (t.powf(power) + s.powf(power) - (t - s).abs().powf(power))
    }
{'fraction_non_alphanumeric': 0.1541922290388548, 'fraction_numerical': 0.024539877300613498, 'mean_word_length': 1.7964551172098342, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3713880', 'n_tokens_mistral': 1661, 'n_tokens_neox': 1537, 'n_words': 412}