# This program is public domain
# Authors: Paul Kienzle, Nadav Horesh
"""
Chirp z-transform.

CZT: callable (x,axis=-1)->array
   define a chirp-z transform that can be applied to different signals
ZoomFFT: callable (x,axis=-1)->array
   define a Fourier transform on a range of frequencies
ScaledFFT: callable (x,axis=-1)->array
   define a limited frequency FFT

czt: array
   compute the chirp-z transform for a signal
zoomfft: array
   compute the Fourier transform on a range of frequencies
scaledfft: array
   compute a limited frequency FFT for a signal
"""
__all__ = ['czt', 'zoomfft', 'scaledfft']

import math, cmath

import numpy as np
from numpy import pi, arange
from scipy.fftpack import fft, ifft, fftshift

class CZT:
    """
    Chirp-Z Transform.

    Transform to compute the frequency response around a spiral.
    Objects of this class are callables which can compute the
    chirp-z transform on their inputs.  This object precalculates
    constants for the given transform.

    If w does not lie on the unit circle, then the transform will be
    around a spiral with exponentially increasing radius.  Regardless,
    angle will increase linearly.

    The chirp-z transform can be faster than an equivalent fft with 
    zero padding.  Try it with your own array sizes to see.  It is 
    theoretically faster for large prime fourier transforms, but not 
    in practice.

    The chirp-z transform is considerably less precise than the
    equivalent zero-padded FFT, with differences on the order of 1e-11 
    from the direct transform rather than the on the order of 1e-15 as 
    seen with zero-padding.

    See zoomfft for a friendlier interface to partial fft calculations.
    """
    def __init__(self, n, m=None, w=1, a=1):
        """
        Chirp-Z transform definition.

        Parameters:
        ----------
        n: int
          The size of the signal
        m: int
          The number of points desired.  The default is the length of the input data.
        a: complex
          The starting point in the complex plane.  The default is 1.
        w: complex or float
          If w is complex, it is the ratio between points in each step.
          If w is float, it serves as a frequency scaling factor. for instance 
          when assigning w=0.5, the result FT will span half of frequncy range 
          (that fft would result) at half of the frequncy step size.

        Returns:
        --------
        CZT:
          callable object f(x,axis=-1) for computing the chirp-z transform on x
        """
        if m is None:
            m = n
        if w is None:
            w = cmath.exp(-1j*pi/m)
        elif type(w) in (float, int):
            w = cmath.exp(-1j*pi/m * w)
        else:
            w = cmath.sqrt(w)
        self.w, self.a = w, a
        self.m, self.n = m, n

        k = arange(max(m,n))
        wk2 = w**(k**2)
        nfft = 2**nextpow2(n+m-1)
        self._Awk2 = (a**-k * wk2)[:n]
        self._nfft = nfft
        self._Fwk2 = fft(1/np.hstack((wk2[n-1:0:-1], wk2[:m])), nfft)
        self._wk2 = wk2[:m]
        self._yidx = slice(n-1, n+m-1)

    def __call__(self, x, axis=-1):
        """
        Parameters:
        ----------
        x: array
          The signal to transform.
        axis: int
          Array dimension to operate over.  The default is the final 
          dimension.

        Returns:
        -------
          An array of the same dimensions as x, but with the length of the
          transformed axis set to m.  Note that this is a view on a much
          larger array.  To save space, you may want to call it as
          y = czt(x).copy()
        """
        x = np.asarray(x)
        if x.shape[axis] != self.n:
            raise ValueError("CZT defined for length %d, not %d" %
                             (self.n, x.shape[axis]))
        # Calculate transpose coordinates, to allow operation on any given axis
        trnsp = np.arange(x.ndim)
        trnsp[[axis, -1]] = [-1, axis]
        x = x.transpose(*trnsp)
        y = ifft(self._Fwk2 * fft(x*self._Awk2, self._nfft))
        y = y[..., self._yidx] * self._wk2
        return y.transpose(*trnsp)


def nextpow2(n):
    """
    Return the smallest power of two greater than or equal to n.
    """
    return int(math.ceil(math.log(n)/math.log(2)))


def ZoomFFT(n, f1, f2=None, m=None, Fs=2):
    """
    Zoom FFT transform definition.

    Computes the Fourier transform for a set of equally spaced
    frequencies.

   Parameters:
   ----------
    n: int
      size of the signal
    m: int
      size of the output
    f1, f2: float
      start and end frequencies; if f2 is not specified, use 0 to f1
    Fs: float
      sampling frequency (default=2)

   Returns:
   -------
    A CZT instance
      A callable object f(x,axis=-1) for computing the zoom FFT on x.

    Sampling frequency is 1/dt, the time step between samples in the
    signal x.  The unit circle corresponds to frequencies from 0 up
    to the sampling frequency.  The default sampling frequency of 2
    means that f1,f2 values up to the Nyquist frequency are in the 
    range [0,1). For f1,f2 values expressed in radians, a sampling 
    frequency of 1/pi should be used.

    To graph the magnitude of the resulting transform, use::

	plot(linspace(f1,f2,m), abs(zoomfft(x,f1,f2,m))).

    Use the zoomfft wrapper if you only need to compute one transform.
    """
    if m is None: m = n
    if f2 is None: f1, f2 = 0., f1
    w = cmath.exp(-2j * pi * (f2-f1) / ((m-1)*Fs))
    a = cmath.exp(2j * pi * f1/Fs)
    return CZT(n, m=m, w=w, a=a)

def ScaledFFT(n, m=None, scale=1.0):
    """
    Scaled fft transform definition.

    Similar to fft, where the frequency range is scaled by a factor 'scale' and
    divided into 'm-1' equal steps.  Like the FFT, frequencies are arranged 
    from 0 to scale*Fs/2-delta followed by -scale*Fs/2 to -delta, where delta 
    is the step size scale*Fs/m for sampling frequence Fs. The intended use is in
    a convolution of two signals, each has its own sampling step.

    This is equivalent to:

        fftshift(zoomfft(x, -scale, scale*(m-2.)/m, m=m))

    For example:

        m,n = 10,len(x)
        sf = ScaledFFT(n, m=m, scale=0.25)
        X = fftshift(fft(x))
        W = linspace(-8, 8*(n-2.)/n, n)
        SX = fftshift(sf(x))
        SW = linspace(-2, 2*(m-2.)/m, m)
        plot(X,W,SX,SW)

     Parameters:
     ----------
      n: int
        Size of the signal
      m: int
        The size of the output.
        Default: m=n
      scale: float
        Frequenct scaling factor.
        Default: scale=1.0

    Returns:
    -------
    function
      A callable f(x,axis=-1) for computing the scaled FFT on x.
    """
    if m is None:
        m = n
    w = np.exp(-2j * pi / m * scale)
    a = w**(m//2)
    transform = CZT(n=n, m=m, a=a, w=w)
    return lambda x, axis=-1: fftshift(transform(x, axis), axes=(axis,))

def scaledfft(x, m=None, scale=1.0, axis=-1):
    """
    Partial  with a frequency scaling.
    See ScaledFFT doc for details

    Parameters:
    ----------
    x:   input array
    m:   int
      The length of the output signal
    scale: float
      A frequency scaling factor
    axis: int
      The array dimension to operate over.  The default is the
      final dimension.

    Returns:
    -------
      An array of the same rank of 'x', but with the size if 
      the 'axis' dimension set to 'm'    
    """
    return ScaledFFT(x.shape[axis], m, scale)(x,axis)

def czt(x, m=None, w=1.0, a=1, axis=-1):
    """
    Compute the frequency response around a spiral.

    Parameters:
    ----------
    x: array
      The set of data to transform.
    m: int
      The number of points desired.  The default is the length of the input data.
    a: complex
      The starting point in the complex plane.  The default is 1.
    w: complex or float
      If w is complex, it is the ratio between points in each step.
      If w is float, it is the frequency step scale (relative to the 
      normal dft frquency step).
    axis: int
      Array dimension to operate over.  The default is the final 
      dimension.

    Returns:
    -------
      An array of the same dimensions as x, but with the length of the
      transformed axis set to m.  Note that this is a view on a much
      larger array.  To save space, you may want to call it as
      y = ascontiguousarray(czt(x))

    See zoomfft for a friendlier interface to partial fft calculations.

    If the transform needs to be repeated, use CZT to construct a 
    specialized transform function which can be reused without 
    recomputing constants. 
    """
    x = np.asarray(x)
    transform = CZT(x.shape[axis], m=m, w=w, a=a)
    return transform(x,axis=axis)

def zoomfft(x, f1, f2=None, m=None, Fs=2, axis=-1):
    """
    Compute the Fourier transform of x for frequencies in [f1, f2].

    Parameters:
    ----------
    m: int
      The number of points to evaluate.  The default is the length of x.
    f1, f2: float
      The frequency range. If f2 is not specified, the range 0-f1 is assumed.
    Fs: float
      The sampling frequency.  With a sampling frequency of
      10kHz for example, the range f1 and f2 can be expressed in kHz.
      The default sampling frequency is 2, so f1 and f2 should be 
      in the range 0,1 to keep the transform below the Nyquist
      frequency.
    x : array
      The input signal.
    axis: int
      The array dimension the transform operates over.  The default is the
      final dimension.

    Returns:
    -------
    array
      The transformed signal.  The fourier transform will be calculate
      at the points f1, f1+df, f1+2df, ..., f2, where df=(f2-f1)/m.

    zoomfft(x,0,2-2./len(x)) is equivalent to fft(x).

    To graph the magnitude of the resulting transform, use::

	plot(linspace(f1,f2,m), abs(zoomfit(x,f1,f2,m))).

    If the transform needs to be repeated, use ZoomFFT to construct a 
    specialized transform function which can be reused without 
    recomputing constants.
    """
    x = np.asarray(x)
    transform = ZoomFFT(x.shape[axis], f1, f2=f2, m=m, Fs=Fs)
    return transform(x,axis=axis)


def _test1(x,show=False,plots=[1,2,3,4]):
    norm = np.linalg.norm

    # Normal fft and zero-padded fft equivalent to 10x oversampling
    over=10
    w = np.linspace(0,2-2./len(x),len(x))
    y = fft(x)
    wover = np.linspace(0,2-2./(over*len(x)),over*len(x))
    yover = fft(x,over*len(x))

    # Check that zoomfft is the equivalent of fft
    y1 = zoomfft(x,0,2-2./len(y))

    # Check that zoomfft with oversampling is equivalent to zero padding
    y2 = zoomfft(x,0,2-2./len(yover), m=len(yover))

    # Check that zoomfft works on a subrange
    f1,f2 = w[3],w[6]
    y3 = zoomfft(x,f1,f2,m=3*over+1)
    w3 = np.linspace(f1,f2,len(y3))
    idx3 = slice(3*over,6*over+1)

    if not show: plots = []
    if plots != []:
        import pylab
    if 0 in plots:
        pylab.figure(0)
        pylab.plot(x)
        pylab.ylabel('Intensity')
    if 1 in plots:
        pylab.figure(1)
        pylab.subplot(311)
        pylab.plot(w,abs(y),'o',w,abs(y1))
        pylab.legend(['fft','zoom'])
        pylab.ylabel('Magnitude')
        pylab.title('FFT equivalent')
        pylab.subplot(312)
        pylab.plot(w,np.angle(y),'o',w,np.angle(y1))
        pylab.legend(['fft','zoom'])
        pylab.ylabel('Phase (radians)')
        pylab.subplot(313)
        pylab.plot(w,abs(y)-abs(y1)) #,w,np.angle(y)-np.angle(y1))
        #pylab.legend(['magnitude','phase'])
        pylab.ylabel('Residuals')
    if 2 in plots:
        pylab.figure(2)
        pylab.subplot(211)
        pylab.plot(w,abs(y),'o',wover,abs(y2),wover,abs(yover))
        pylab.ylabel('Magnitude')
        pylab.title('Oversampled FFT')
        pylab.legend(['fft','zoom','pad'])
        pylab.subplot(212)
        pylab.plot(wover,abs(yover)-abs(y2),
                   w,abs(y)-abs(y2[0::over]),'o',
                   w,abs(y)-abs(yover[0::over]),'x')
        pylab.legend(['pad-zoom','fft-zoom','fft-pad'])
        pylab.ylabel('Residuals')
    if 3 in plots:
        pylab.figure(3)
        ax1=pylab.subplot(211)
        pylab.plot(w,abs(y),'o',w3,abs(y3),wover,abs(yover),
                   w[3:7],abs(y3[::over]),'x')
        pylab.title('Zoomed FFT')
        pylab.ylabel('Magnitude')
        pylab.legend(['fft','zoom','pad'])
        pylab.plot(w3,abs(y3),'x')
        ax1.set_xlim(f1,f2)
        ax2=pylab.subplot(212)
        pylab.plot(wover[idx3],abs(yover[idx3])-abs(y3),
                   w[3:7],abs(y[3:7])-abs(y3[::over]),'o',
                   w[3:7],abs(y[3:7])-abs(yover[3*over:6*over+1:over]),'x')
        pylab.legend(['pad-zoom','fft-zoom','fft-pad'])
        ax2.set_xlim(f1,f2)
        pylab.ylabel('Residuals')
    if plots != []:
        pylab.show()

    err = norm(y-y1)/norm(y)
    #print "direct err %g"%err
    assert err < 1e-10, "error for direct transform is %g"%(err,)
    err = norm(yover-y2)/norm(yover)
    #print "over err %g"%err
    assert err < 1e-10, "error for oversampling is %g"%(err,)
    err = norm(yover[idx3]-y3)/norm(yover[idx3])
    #print "range err %g"%err
    assert err < 1e-10, "error for subrange is %g"%(err,)

def _testscaled(x):
    n = len(x)
    norm = np.linalg.norm
    assert norm(fft(x)-scaledfft(x)) < 1e-10
    assert norm(fftshift(fft(x))[n/4:3*n/4] - fftshift(scaledfft(x,scale=0.5,m=n/2))) < 1e-10

def test(demo=None,plots=[1,2,3]):
    # 0: Gauss
    t = np.linspace(-2,2,128)
    x = np.exp(-t**2/0.01)
    _test1(x, show=(demo==0), plots=plots)

    # 1: Linear
    x=[1,2,3,4,5,6,7]
    _test1(x, show=(demo==1), plots=plots)

    # Check near powers of two
    _test1(range(126-31), show=False)
    _test1(range(127-31), show=False)
    _test1(range(128-31), show=False)
    _test1(range(129-31), show=False)
    _test1(range(130-31), show=False)

    # Check transform on n-D array input
    x = np.reshape(np.arange(3*2*28),(3,2,28))
    y1 = zoomfft(x,0,2-2./28)
    y2 = zoomfft(x[2,0,:],0,2-2./28)
    err = np.linalg.norm(y2-y1[2,0])
    assert err < 1e-15, "error for n-D array is %g"%(err,)

    # 2: Random (not a test condition)
    if demo==2:
        x = np.random.rand(101)
        _test1(x, show=True, plots=plots)

    # 3: Spikes
    t=np.linspace(0,1,128)
    x=np.sin(2*pi*t*5)+np.sin(2*pi*t*13)
    _test1(x, show=(demo==3), plots=plots)

    # 4: Sines
    x=np.zeros(100)
    x[[1,5,21]]=1
    _test1(x, show=(demo==4), plots=plots)

    # 5: Sines plus complex component
    x += 1j*np.linspace(0,0.5,x.shape[0])
    _test1(x, show=(demo==5), plots=plots)

    # 6: Scaled FFT on complex sines
    x += 1j*np.linspace(0,0.5,x.shape[0])
    if demo == 6:
        demo_scaledfft(x,0.25,200)
    _testscaled(x)
  

def demo_scaledfft(v, scale, m):
    import pylab
    shift = pylab.fftshift
    n = len(v)
    x = pylab.linspace(-0.5, 0.5 - 1./n, n)
    xz = pylab.linspace(-scale*0.5, scale*0.5*(m-2.)/m, m)
    pylab.figure()
    pylab.plot(x, shift(abs(fft(v))), label='fft')
    pylab.plot(x, shift(abs(scaledfft(v))),'ro', label='x1 scaled fft')
    pylab.plot(xz, abs(zoomfft(v, -scale, scale*(m-2.)/m, m=m)),
               'bo',label='zoomfft')
    pylab.plot(xz, shift(abs(scaledfft(v, m=m, scale=scale))), 
               'gx', label='x'+str(scale)+' scaled fft')
    pylab.gca().set_yscale('log')
    pylab.legend()
    pylab.show()

if __name__ == "__main__":
    # Choose demo in [0,4] to show plot, or None for testing only
    test(demo=None)

