#!/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