Exemplo n.º 1
0
    def _sample_colored_noise(self, n):
        """Generate colored noise increments at specified times from zero."""
        check_positive_integer(n)
        n = n + 1
        if self._n != n:
            self._n = n

            self._half = (n + 1) // 2
            self._frequencies = np.fft.fftfreq(n, self.t)
            self._scale = [
                np.sqrt(0.5 * (1 / w) ** self.beta)
                for w in self._frequencies[1 : self._half]
            ]

        gn_real = np.random.normal(size=self._half - 1)
        gn_imag = np.random.normal(size=self._half - 1)
        fft = self._scale * (gn_real + 1j * gn_imag)

        if n % 2 == 0:
            f = np.concatenate(
                (
                    [0],
                    fft,
                    [
                        np.sqrt(0.5 * (1 / -self._frequencies[self._half]) ** self.beta)
                        * np.random.normal()
                    ],
                    np.conj(fft)[::-1],
                )
            )
        else:
            f = np.concatenate(([0], fft, np.conj(fft)[::-1]))

        return np.fft.ifft(f).real / np.std(f)
Exemplo n.º 2
0
    def _sample_poisson_process(self, n=None, length=None):
        """Generate a realization of a Poisson process.

        Generate a poisson process sample up to count of length if time=False,
        otherwise generate a sample up to time t=length if time=True
        """
        if n is not None:
            check_positive_integer(n)

            exponentials = self.rng.exponential(scale=1.0 / self.rate, size=n)

            s = np.array([0] + list(np.cumsum(exponentials)))
            return s
        elif length is not None:
            check_positive_number(length, "Sample length")

            t = 0
            times = [0]
            exp_rate = 1.0 / self.rate

            while t < length:
                t += self.rng.exponential(scale=exp_rate)
                times.append(t)

            return np.array(times)
        else:
            raise ValueError("Must provide either argument n or length.")
Exemplo n.º 3
0
    def _sample_squared_bessel_process(self, n):
        """Generate a realization of a squared Bessel process."""
        check_positive_integer(n)

        samples = [self._sample_brownian_motion(n) for _ in range(self.dim)]

        return np.array([sum(map(lambda x: x ** 2, coord)) for coord in zip(*samples)])
Exemplo n.º 4
0
    def _sample_chinese_restaurant(self, n, partition=False):
        """Generate a Chinese restaurant process with n customers."""
        check_positive_integer(n)

        c = [[1]]
        s = [0]
        num_tables = 1
        table_range = [0, 1]

        for k in range(2, n + 1):
            p = [
                1.0 * (len(c[t]) - self.discount) / (k - 1 + self.strength)
                for t in table_range[:-1]
            ]
            p.append(1.0 * (self.strength + num_tables * self.discount) /
                     (k - 1 + self.strength))
            table = self.rng.choice(table_range, p=p)
            if table == num_tables:
                num_tables += 1
                table_range.append(num_tables)
                c.append([])
            c[table].append(k - 1)
            s.append(table)

        if partition:
            return np.array([np.array(t) for t in c], dtype=object)
        else:
            return np.array(s)
    def _daviesharte(self, n):
        """Generate a fractional Gaussian noise using davies-harte method.

        Uses Davies and Harte method (exact method) from:
        Davies, Robert B., and D. S. Harte. "Tests for Hurst effect."
        Biometrika 74, no. 1 (1987): 95-101.
        """
        check_positive_integer(n)

        # For scaling to interval [0, T]
        increment = self.t / n
        scale = increment**self.hurst

        # If H = 0.5 then just generate a standard Brownian motion, otherwise
        # proceed with the Davies Harte method
        if self.hurst == 0.5:
            return self.rng.normal(scale=scale, size=n)

        else:
            # Generate some more fGns to use power-of-two FFTs for speed.
            m = 2**(n - 2).bit_length() + 1
            sqrt_eigenvals = self._dh_sqrt_eigenvals(self.hurst, m)

            # irfft results will be normalized by (2(m-1))**(3/2) but we only
            # want to normalize by 2(m-1)**(1/2).
            scale *= 2**(1 / 2) * (m - 1)

            w = self.rng.normal(scale=scale, size=2 * m).view(complex)
            w[0] = w[0].real * 2**(1 / 2)
            w[-1] = w[-1].real * 2**(1 / 2)

            # Resulting z is fft of sequence w.
            return np.fft.irfft(sqrt_eigenvals * w)[:n]
Exemplo n.º 6
0
    def _sample_cauchy_process(self, n):
        """Generate a realization of a Cauchy process."""
        check_positive_integer(n)

        delta_t = 1.0 * self.t / n
        times = np.cumsum(levy.rvs(loc=0, scale=delta_t**2 / 2, size=n))
        times = np.insert(times, 0, [0])
        return self._sample_brownian_motion_at(times)
Exemplo n.º 7
0
def test_check_positive_integer(increments_fixture):
    if not isinstance(increments_fixture, int):
        with pytest.raises(TypeError):
            check_positive_integer(increments_fixture)
    elif increments_fixture <= 0:
        with pytest.raises(ValueError):
            check_positive_integer(increments_fixture)
    else:
        assert check_positive_integer(increments_fixture) is None
Exemplo n.º 8
0
    def _sample_gamma_process(self, n):
        """Sample a Gamma process."""
        check_positive_integer(n)
        delta_t = 1.0 * self.t / n

        shape = 1.0 * self.mean**2 * delta_t / self.variance
        scale = 1.0 * self.variance / self.mean

        samples = np.cumsum(self.rng.gamma(shape=shape, scale=scale, size=n))
        return np.concatenate(([0], samples))
Exemplo n.º 9
0
    def _sample_gaussian_noise(self, n):
        """Generate a realization of Gaussian noise.

        Generate a Gaussian noise realization with n increments.
        """
        check_positive_integer(n)
        delta_t = 1.0 * self.t / n

        noise = self.rng.normal(scale=np.sqrt(delta_t), size=n)

        return noise
Exemplo n.º 10
0
    def _sample_geometric_brownian_motion(self, n, initial=1.0):
        """Generate a realization of geometric Brownian motion."""
        check_positive_integer(n)
        check_positive_number(initial, "Initial")

        # Opt for repeated use
        if self._n != n:
            self._n = n
            self._line = generate_times(self.drift - self.volatility**2 / 2.0,
                                        n)

        noise = self.volatility * self._brownian_motion.sample(n)

        return initial * np.exp(self._line + noise)
Exemplo n.º 11
0
    def sample(self, n):
        """Generate a realization of the Markov chain.

        :param int n: the number of steps of the Markov chain to generate.
        """
        check_positive_integer(n)

        states = range(self.num_states)

        markov_chain = [self.rng.choice(states, p=self.initial)]
        for _ in range(n - 1):
            markov_chain.append(
                self.rng.choice(states, p=self.transition[markov_chain[-1]]))

        return np.array(markov_chain)
Exemplo n.º 12
0
    def _sample_variance_gamma_process(self, n):
        """Generate a realization of a variance gamma process."""
        check_positive_integer(n)

        delta_t = 1.0 * self.t / n
        shape = delta_t / self.variance
        scale = self.variance

        gammas = self.rng.gamma(shape=shape, scale=scale, size=n)
        gn = self.gn.sample(n)

        increments = self.drift * gammas + self.scale * np.sqrt(gammas) * gn

        samples = np.cumsum(increments)

        return np.concatenate(([0], samples))
Exemplo n.º 13
0
    def _sample(self, n, initial=1.0):
        """Generate a realization of a diffusion process using Euler-Maruyama."""
        check_positive_integer(n)
        check_numeric(initial, "Initial")

        delta_t = 1.0 * self.t / n
        gns = self._sample_gaussian_noise(n)

        s = [initial]
        t = 0
        for k in range(n):
            t += delta_t
            initial += (self._speed(t) * (self._mean(t) - initial) * delta_t +
                        self._vol(t) * initial**self._volexp(initial) * gns[k])
            s.append(initial)

        return np.array(s)
Exemplo n.º 14
0
 def _sample_random_walk_increments(self, n):
     """Generate a sample of random walk increments."""
     check_positive_integer(n)
     return self.rng.choice(self.steps, p=self.p, size=n)
Exemplo n.º 15
0
 def _sample_bessel_process(self, n):
     """Generate a realization of a Bessel process."""
     check_positive_integer(n)
     samples = [self._sample_brownian_motion(n) for _ in range(self.dim)]
     return np.array([np.linalg.norm(coord) for coord in zip(*samples)])
Exemplo n.º 16
0
 def _set_times(self, n):
     if self._n != n:
         check_positive_integer(n)
         self._n = n
         self._times = generate_times(self.t, n)
Exemplo n.º 17
0
    def _sample_bernoulli(self, n):
        """Generate a Bernoulli process realization."""
        check_positive_integer(n)

        return np.array(
            [1 if trial < self.p else 0 for trial in self.rng.uniform(size=n)])