File: noise_generator.py

package info (click to toggle)
python-multipletau 0.3.3%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 380 kB
  • sloc: python: 1,557; makefile: 15
file content (118 lines) | stat: -rw-r--r-- 3,257 bytes parent folder | download | duplicates (4)
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
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Methods for correlated noise generation"""

from __future__ import division
from __future__ import print_function

import numpy as np

__all__ = ["noise_exponential", "noise_cross_exponential"]


def noise_exponential(N, tau=20, variance=1, deltat=1):
    """Generate exponentially correlated noise.

    Parameters
    ----------
    N : integer
       Total number of samples
    tau : float
       Correlation time of the exponential in `deltat`
    variance : float
       Variance of the noise
    deltat : float
       Bin size of output array, defines the time scale of `tau`

    Returns
    -------
    a : ndarray
       Exponentially correlated noise.
    """
    # time constant (inverse of correlationtime tau)
    g = deltat / tau
    # variance
    s0 = variance

    # normalization factor (memory of the trace)
    exp_g = np.exp(-g)
    one_exp_g = 1 - exp_g
    z_norm_factor = np.sqrt(1 - np.exp(-2 * g)) / one_exp_g

    # create random number array
    # generates random numbers in interval [0,1)
    randarray = np.random.random(N)
    # make numbers random in interval [-1,1)
    randarray = 2 * (randarray - 0.5)

    # simulate exponential random behavior
    a = np.zeros(N)
    a[0] = one_exp_g * randarray[0]
    for i in np.arange(N - 1) + 1:
        a[i] = exp_g * a[i - 1] + one_exp_g * randarray[i]

        # Solving the equation iteratively leads to this equation:
        # j = np.arange(i)
        # a[i] = a[0]*exp_g**(i) + \
        #       one_exp_g)*np.sum(exp_g**(i-1-j)*randarray[1:i+1])

    a = a * z_norm_factor * s0
    return a


def noise_cross_exponential(N, tau=20, variance=1, deltat=1):
    """Generate exponentially cross-correlated noise.

    Parameters
    ----------
    N : integer
       Total number of samples
    tau : float
       Correlation time of the exponential in `deltat`
    variance : float
       Variance of the noise
    deltat : float
       Bin size of output array, defines the time scale of `tau`

    Returns
    -------
    a, randarray : ndarrays
       Array `a` has positive exponential correlation to the 'truly'
       random array `randarray`.
    """
    # time constant (inverse of correlationtime tau)
    g = deltat / tau
    # variance
    s0 = variance
    # normalization factor (memory of the trace)
    exp_g = np.exp(-g)
    one_exp_g = 1 - exp_g
    z_norm_factor = np.sqrt(1 - np.exp(-2 * g)) / one_exp_g

    # create random number array
    # generates random numbers in interval [0,1)
    randarray = np.random.random(N)
    # make numbers random in interval [-1,1)
    randarray = 2 * (randarray - 0.5)

    # simulate exponential random behavior
    a = np.zeros(N)
    a[0] = one_exp_g * randarray[0]

    b = np.zeros(N)
    b[0] = one_exp_g * randarray[0]
    # slow
    # for i in np.arange(N-1)+1:
    #    for j in np.arange(i-1):
    #        a[i] += exp_g**j*randarray[i-j]
    #    a[i] += one_exp_g*randarray[i]
    # faster
    j = np.arange(N + 5)
    for i in np.arange(N - 1) + 1:
        a[i] += np.sum(exp_g**j[2:i + 1] * randarray[2:i + 1][::-1])
        a[i] += one_exp_g * randarray[i]

    a *= z_norm_factor * s0
    randarray = randarray * z_norm_factor * s0

    return a, randarray