Source code for gridcells.analysis.signal

'''
===============================================================
:mod:`gridcells.analysis.signal` - signal analysis
===============================================================

The can be e.g. filtering, slicing, correlation analysis, up/down-sampling, etc.

.. autosummary::

    acorr
    corr
'''
from __future__ import absolute_import, print_function, division

import os

import numpy as np

# Do not import when in RDT environment
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd:
    from . import _signal



[docs]def corr(a, b, mode='onesided', lag_start=None, lag_end=None): ''' An enhanced correlation function of two real signals, based on a custom C++ code. This function uses dot product instead of FFT to compute a correlation function with range restricted lags. Thus, for a long-range of lags and big arrays it can be slower than the numpy.correlate (which uses fft-based convolution). However, for arrays in which the number of lags << max(a.size, b.size) the computation time might be much shorter than using convolution to calculate the full correlation function and taking a slice of it. Parameters: a, b : ndarray One dimensional numpy arrays (in the current implementation, they will be converted to dtype=double if not already of that type. mode : str, optional A string indicating the size of the output: ``onesided`` : range of lags is [0, b.size - 1] ``twosided`` : range of lags is [-(a.size - 1), b.size - 1] ``range`` : range of lags is [-lag_start, lag_end] lag_start, lag_end : int, optional Initial and final lag value. Only used when mode == 'range' output : numpy.ndarray with shape (1, ) and dtype.float A 1D array of size depending on mode .. note:: This function always returns a numpy array with dtype=float. .. seealso:: :py:func:`acorr` ''' a = np.require(a, np.float, 'F') b = np.require(b, np.float, 'F') sz1 = a.size sz2 = b.size if sz1 == 0 or sz2 == 0: raise TypeError("Both input arrays must have non-zero size!") if mode == 'onesided': return _signal.correlation_function(a, b, 0, sz2 - 1) elif mode == 'twosided': return _signal.correlation_function(a, b, -(sz1 - 1), sz2 - 1) elif mode == 'range': lag_start = int(lag_start) lag_end = int(lag_end) if lag_start <= -sz1 or lag_end >= sz2: raise ValueError("Lag range must be in the range " "[{0}, {1}]".format(-(sz1 - 1), sz2 - 1)) return _signal.correlation_function(a, b, lag_start, lag_end) else: raise ValueError("mode must be one of 'onesided', 'twosided', or " "'range'")
[docs]def acorr(sig, max_lag=None, norm=False, mode='onesided'): ''' Compute an autocorrelation function of a real signal. Parameters ---------- sig : numpy.ndarray The signal, 1D vector, to compute an autocorrelation of. max_lag : int, optional Maximal number of lags. If mode == 'onesided', the range of lags will be [0, max_lag], i.e. the size of the output will be (max_lag+1). If mode == 'twosided', the lags will be in the range [-max_lag, max_lag], and so the size of the output will be 2*max_lag + 1. If max_lag is None, then max_lag will be set to len(sig)-1 norm : bool, optional Whether to normalize the auto correlation result, so that res(0) = 1 mode : string, optional ``onesided`` or ``twosided``. See description of max_lag output : numpy.ndarray A 1D array, size depends on ``max_lag`` and ``mode`` parameters. Notes ----- If the normalisation constant is zero (i.e. the input array is zero), this function will return a zero array. ''' if max_lag is None: max_lag = len(sig) - 1 if mode == 'onesided': c = corr(sig, sig, mode='range', lag_start=0, lag_end=max_lag) elif mode == 'twosided': c = corr(sig, sig, mode='range', lag_start=-max_lag, lag_end=max_lag) else: raise ValueError("mode can be either 'onesided' or 'twosided'!") if norm: maximum = np.max(np.abs(c)) if maximum != 0.: c /= maximum return c