Esempio n. 1
0
File: swt.py Progetto: cem3394/ante
def swt_rot_cum_wav_svar(WJt, VJ0t, method='power'):
    """
    swt_cum_wav_svar -- Calculate cumulative sample variance of SWT wavelet coefficients.
    
     NAME
       swt_cum_wav_svar -- Calculate cumulative sample variance of 
             SWT wavelet coefficients.
    
     INPUTS
       WJt          -  JxN dwtArray of SWT wavelet coefficents
                       where N = number of time intervals
                             J = number of levels
                       they can be already rotated or not
       VJ0t         -  N dwtArray of SWT J0 scaling coefficents
                       they can be already rotated or not
       method       - variance estimate returned
                       'power' = |W^2|/N
                       'cum'   = cumulative variance
                       'cumsc' = cumulative "scaled" (see pag.189)
                       Default: 'power' 
    
     OUTPUTS
       cwsvar       -  cumulative wavelet sample variance (dwtArray).
    
     DESCRIPTION
       'cumsc' method is equivalent to the one on pag.189 of P&W .
    
     ALGORITHM
    
       cwsvar[j,t] = 1/N * sum( WJt^2 subscript(j,u+nuH_j mod N)) 
                        for t = 0,N-1 at jth level
       for j in range(J):
        rcwsvar[j,:] = cswvar[j,:] - t*cwsvarN[j]/(N-1.)
      
     SEE ALSO
       swt_cir_shift, swt
    """
    
    if method not in ('power','cum','cumsc'):
        raise ValueError('Valid methods are: "power", "cum" or "cumsc"')
    
    # check input
    if type(WJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if WJt.info['Type'] is not 'Wavelet':
        raise TypeError('First input array does not contain Wavelet coefficients but {} coefficients'.format(WJt.info['Type']))
    if type(VJ0t) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if VJ0t.info['Type'] is not 'Scaling':
        raise TypeError('Second input array does not contain Scaling coefficients but {} coefficients'.format(VJ0t.info['Type']))
    
    # get dimensions
    try:
        J, N   = WJt.shape
    except ValueError:
        N = WJt.size
        J=1
    if len(VJ0t.shape)>1:
        raise ValueError('Only J0 level scaling coefficient should be given')
        
    # rotate if they are not yet aligned
    WJt,VJ0t = swt_cir_shift(WJt, VJ0t) # the check for rotation is done in swt_cir_shift

    pWJt = WJt**2; pVJ0t = VJ0t**2
    
    if method=='power':
        Watt = dict(WJt.info.items() + {'Type':'WavRotPower'}.items())
        Vatt = dict(VJ0t.info.items() + {'Type':'ScalRotPower'}.items())
        return dwtArray(pWJt, info=Watt),dwtArray(pVJ0t, info=Vatt)
    
    cwsvar = np.cumsum(pWJt, axis=1)/N
    swsvar = np.cumsum(pVJ0t)/N

    if method=='cum':
        Watt = dict(WJt.info.items() + {'Type':'WavRotCumVar'}.items())
        Vatt = dict(VJ0t.info.items() + {'Type':'ScalRotCumVar'}.items())
        return dwtArray(cwsvar, info=Watt),dwtArray(swsvar, info=Vatt)

    # compute rotated cumulative variance
    cwsvarN = cwsvar[:,-1]
    swsvarN = swsvar[-1]
    
    t = np.arange(N, dtype=np.float64)

    rcwsvar = cwsvar - t*cwsvarN[:,np.newaxis]/(N-1)
    rswsvar = swsvar - t*swsvarN/(N-1)

    Watt = dict(WJt.info.items() + {'Type':'WavRotCumScVar'}.items())
    Vatt = dict(VJ0t.info.items() + {'Type':'ScalRotCumScVar'}.items())
    return dwtArray(rcwsvar, info=Watt),dwtArray(rswsvar, info=Vatt)
Esempio n. 2
0
File: swt.py Progetto: cem3394/ante
def swt(X, wtf='d4', nlevels='conservative', RetainVJ=False):
    """
    function swt(X, wtf='d4', nlevels='conservative', RetainVJ=False)
    
    NAME
       swt -- Compute the (partial) stationary wavelet transform (SWT).
    
    INPUTS
       X          -- set of observations 
                    (vector of length NX)
       wtf        -- (optional) wavelet transform filter name
                     (string, case-insensitve or wtf struct).
                     Default:  'd4'
       nlevels    -- (optional) maximum level J0 (integer) 
                     or method of calculating J0 (string).
                     Valid values: integer>0 or a valid method name
                     Default:  'conservative'
       RetainVJ   -- (optional) boolean flag to retain V at each
                     decomposition level
                     Default: False
    
    OUTPUTS
       WJt        -- SWT wavelet coefficents (J x NW array) dwtArray
       VJt        -- SWT scaling coefficients ((1 or J) x NW vector) dwtArray
    
    DESCRIPTION
       swt calculates the wavelet and scaling coefficients using the stationary wavelet transform (SWT).
    
       The optional input arguments have default values:
       * wtf      -- 'd4' filter
       * nlevels  -- 'convservative' --> J0 < log2( N / (L-1) + 1)
    
       The output arguments include an info attribute with metadata.
       info is a dictionary with the following fields:
       * Transform  -- name of transform ('SWT')
       * WTF        -- name of wavelet transform filter or a wtf_s struct.
       * NX         -- number of observations in original series (= length(X))
       * NW         -- number of wavelet coefficients
       * J0         -- number of levels of partial decompsition.
       * Aligned    -- Boolean flag indicating whether coefficients are aligned
                       with original series (1 = true) or not (0 = false).
       * RetainVJ -- Boolean flag indicating whether VJ scaling coefficients
                       at all levels have been retained (1= true) or not (0 = false).
    
    EXAMPLE
       WJt, VJt = swt(X, 'd4', 6)
    
    NOTES 
       pages 177-178 of P&W 
    
    SEE ALSO
       swtj, swt_filter, swt_choose_nlevels, nargerr, argterr, dwtArray
    """

    # Get a valid wavelet transform filter coefficients struct.
    wtf_s = wtfilter(wtf)
  
    wtfname = wtf_s.Name
    gt = wtf_s.g
    ht = wtf_s.h
    L  = wtf_s.L

    # ensure X is a numpy array
    X = np.array(X)
    if len(X.shape)>1:
        raise ValueError('SWT: Input array must be one-dimensional')
    #  N    = length of original series
    N = X.size
        
    #  If nlevels is an integer > 0, set J0 = nlevels.
    #  otherwise, select J0 based on choice method specified.
    if isinstance(nlevels, str):
        J0 = swt_choose_nlevels(nlevels, wtfname, N)
    elif isinstance(nlevels, int):
        if nlevels > 0:
            J0 = nlevels
        else:
            raise ValueError('SWT:negativeJ0, nlevels must be an integer greater than 0.')
    else:
        raise ValueError('SWT:invalidNLevelsValue')
    
    if (J0 < 0):
        raise ValueError('SWT:negativeJ0')
    
    if (2**J0 > N):
        raise ValueError('SWT:LargeJ0', 'JO must be < log2(Number of samples).')

    # NW = length of the extended series = number of coefficients
    NW = X.size
    # Initialize the scale (Vin) for first level by setting it equal to X
    Vin = X
    # Pre-allocate memory.
    WJt = np.ndarray((J0, NW), dtype=np.float64)*np.nan
    if RetainVJ:
        VJt = np.ndarray((J0, NW), dtype=np.float64)*np.nan
    else:
        VJt = np.ndarray((NW), dtype=np.float64)*np.nan

    # Do the SWT.
    from swtj import swtj
    bw = np.ndarray((J0,2))*np.nan
    for j in range(J0):
        Wt_j, Vout = swtj(Vin, j+1, ht, gt)
        WJt[j,:]   = Wt_j
        Vin        = Vout
        if RetainVJ:
            VJt[j,:] = Vout
            
        # boundary values 198 
        L_j     = equivalent_filter_width(L, j+1)
        bw[j,0] = min(L_j - 2, NW-1) #max index to the left
        #bw[j,1] = np.nan #Bc are only at the beginning
    if not RetainVJ:
        VJt[:] = Vout
        bv     = bw[-1,:]
    else:
        bv     = bw

    # Update attributes
    att = {'Transform':'SWT',
           'WTF'      : wtfname,
           'N'        : N,
           'NW'       : NW,
           'J0'       : J0,
           'Aligned'  : False,
           'RetainVJ' : RetainVJ,
           'Type'     : 'Wavelet',
           'BCs'      : bw
           }
    WJt = dwtArray(WJt, info=att)

    att = {'Transform':'SWT',
           'WTF'      : wtfname,
           'N'        : N,
           'NW'       : NW,
           'J0'       : J0,
           'Aligned'  : False,
           'RetainVJ' : RetainVJ,
           'Type'     : 'Scaling',
           'BCs'      : bv
           }
    VJt = dwtArray(VJt, info=att)
    
    return WJt, VJt
Esempio n. 3
0
File: swt.py Progetto: cem3394/ante
def swt_cir_shift(WJt, VJ0t, subtract_mean_VJ0t=True):
    """
    shift_swt_coef -- shift the SWT wavelet and scaling coefficients.
    
    NAME
        shift_swt_coef -- Shift the SWT wavelet and scaling coefficients.

    INPUTS
        WJt          =  JxN dwtArray of SWT wavelet coefficents
                        where N = number of time intervals,
                              J = number of levels
        VJ0t         =  N dwtArray of SWT scaling coefficients at level J0.

        subtract_mean_VJ0t = (optional) subtract mean value of scaling coefficient 
                        from itself
                        Default: True

    OUTPUTS
        W  = shifted wavelet coefficients with boundary conditions (dwtArray)
        V  = shifted scaling coefficients with boundary conditions (dwtArray)
        boundaries = demarcing the circularly shifted SWT coefficients influenced 
                     by the circularity conditions
        bw  = Jx2 array with min/max indices of wavelet boundary coefficients
        bv  = Jx2 array with min/max indices of scaling boundary coefficients

    DESCRIPTION
       The SWT coefficients are circularly shifted at each level so as to 
       properly align the coefficients with the original data series. See P&W fig 183

    SEE ALSO
       swt, swt_filter
       multi_yoffset_plot
    """
    
    # check input
    if type(WJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if WJt.info['Type'] is not 'Wavelet':
        raise TypeError('First input array does not contain Wavelet coefficients but {} coefficients'.format(WJt.info['Type']))
    if type(VJ0t) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if VJ0t.info['Type'] is not 'Scaling':
        raise TypeError('Second input array does not contain Scaling coefficients but {} coefficients'.format(VJ0t.info['Type']))
    
    wtf_s = wtfilter(WJt.info['WTF'])
    L  = wtf_s.L

    wtfname       = WJt.info['WTF']
    N             = WJt.info['N']
    NW            = WJt.info['NW']
    J0            = WJt.info['J0']
    
    Nm = min(N,NW)

    if WJt.info['Aligned']:
        print ('WARNING (ante.swt.swt_cir_shift): Wavelet coefficients are already aligned')
        W = WJt
    else:
        if WJt!=dwtArray([]):
            W = np.ndarray(WJt.shape)*np.nan; bw = np.ndarray((J0,2))*np.nan
            for j in range(J0):
                # shift wavelet coefficients
                nuHj = advance_wavelet_filter(wtfname, j+1)
                W[j,:] = np.roll(WJt[j,:], nuHj)
                
                #Calculate circularly shifted wavelet coefficient boundary indices at jth level
                L_j   = equivalent_filter_width(L, j+1)
        
                bw[j,0] = L_j - 2 - np.abs(nuHj) #max index to the left
                bw[j,1] = Nm - abs(nuHj) #min index to the right
            W = W[:,:Nm]
            # Update attributes
            att = dict(WJt.info.items() +
                       {'Aligned':True,
                        'BCs'    :bw
                        }.items())
            W = dwtArray(W, info=att)
        else: # if an empty array was given, do nothing and return it
            W = WJt

    if VJ0t.info['Aligned']:
        print ('WARNING (ante.swt.swt_cir_shift): Wavelet coefficients are already aligned')
        V = VJ0t
    else:
        V = np.ndarray(VJ0t.shape)*np.nan; bv = np.ndarray((2,))*np.nan
        # shift scaling coefficients
        if VJ0t!=dwtArray([]):
            nuGj = advance_scaling_filter(wtfname, J0)
            if subtract_mean_VJ0t:
                VJ0t = VJ0t - VJ0t.mean()
            V    = np.roll(VJ0t, nuGj)
    
            bv[0] = L_j - 2 - np.abs(nuGj) #max index to the left
            bv[1] = Nm - np.abs(nuGj) #min index to the right
            # Update attributes
            att = dict(VJ0t.info.items() +
                       {'Aligned':True,
                        'BCs'    :bv
                        }.items())
            V = dwtArray(V, info=att)
        else: # if an empty array was given, do nothing and return it
            V = VJ0t

    return W,V
Esempio n. 4
0
File: swt.py Progetto: cem3394/ante
def iswt_details(WJt):
    """
    iswt_details -- Calculate details via inverse stationary wavelet transform (ISWT).

    NAME
       iswt_details -- Calculate details via inverse stationary wavelet transform (ISWT).
    
    INPUTS
       WJt          -  NxJ array of SWT wavelet coefficents
                       where N  = number of time points
                             J = number of levels.
                       The array must be a dwtArray (containing the information on the transform)
    
    OUTPUT
       DJt          -  JxN dwtArray of reconstituted details of data series for J0 scales.
       att          -  structure containing ISWT transform attributes.
    
    DESCRIPTION
       The output parameter att is a structure with the following fields:
           name      - name of transform (= 'SWT')
           wtfname   - name of SWT wavelet filter
           npts      - number of observations (= length(X))
           J0        - number of levels 
    
    EXAMPLE
       DJt = iswt_details(WJt)
    
    SEE ALSO
       iswtj, iswt, iswt_smooth, swt_filter, swt
    """
    
    # Get a the wavelet transform filter coefficients.
    if type(WJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if WJt.info['Type'] is not 'Wavelet':
        raise TypeError('Input array does not contain Wavelet coefficients but {} coefficients'.format(WJt.info['Type']))
    wtfname = WJt.info['WTF']
    wtf_s   = wtfilter(wtfname)
  
    gt = wtf_s.g
    ht = wtf_s.h
    L  = wtf_s.L

    J,N = WJt.shape
    J0  = J

    zeroj = np.zeros(N)
    DJt   = np.zeros((J, N))

    from swtj import iswtj 
    for j in range(J0-1,-1,-1):
        Vin = zeroj
        Win = WJt[j,:]
        for jj in range(j,-1,-1):
            Vout = iswtj(Win, Vin, jj+1, ht, gt)
            Win = zeroj
            Vin = Vout
        DJt[j,:] = Vout
    
    # boundary values 199 
    bw = np.ndarray((J0,2), dtype=np.int16)*np.nan
    for j in range(J0):
        #Calculate wavelet coefficient boundary indices at jth level
        L_j     = equivalent_filter_width(L, j+1)
        bw[j,0] = L_j-2; bw[j,1]= -L_j+1
    # Update attributes
    att = dict(WJt.info.items() +
               {'Transform':'ISWT',
                'Type'     :'Detail',
                'BCs'      :bw}.items())
    
    DJt = dwtArray(DJt, info=att)

    return DJt
Esempio n. 5
0
File: swt.py Progetto: cem3394/ante
def iswt_smooth(VJt):
    """
    iswt_smooth -- Calculate smooths at J0 level via inverse stationary wavelet transform (ISWT).

    NAME
       iswt_smooth -- Calculate smooths at J0 level via inverse stationary wavelet transform (ISWT).
    
    INPUTS
       VJt          =  N dwtArray of SWT scaling coefficients at J0 level.
    
    OUTPUT
       SJOt         =  dwtArray of reconstituted smoothed data series.
    
    DESCRIPTION
    
    EXAMPLE
       SJt = iswt_smooth(VJt)
    
    SEE ALSO
       iswtj, iswt, iswt_details, swt_filter, swt
    """

    # Get the wavelet transform filter coefficients.
    if type(VJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if VJt.info['Type'] is not 'Scaling':
        raise TypeError('Input array does not contain Scaling coefficients but {} coefficients'.format(VJt.info['Type']))
    wtfname = VJt.info['WTF']
    J0      = VJt.info['J0']
    wtf_s   = wtfilter(wtfname)
    gt = wtf_s.g
    ht = wtf_s.h
    L  = wtf_s.L

    if len(VJt.shape)>1:
        if VJt.info['RetainVJ']:
            VJt = VJt[-1,:]
        else:
            raise TypeError('The input is a multidimensional array but {} SWT\
             has been computed with RetainVJ=False. \n')
    N = VJt.size

    # initialize arrays
    zeroj = np.zeros(N)

    Vin = VJt

    #import pyximport; pyximport.install()
    from swtj import iswtj
    for j in range(J0-1,-1,-1):
        Vout = iswtj(zeroj, Vin, j+1, ht, gt)
        Vin  = Vout

    SJt = Vout
    
    # boundary values pag.199 P&W
    L_j = equivalent_filter_width(L, J0)
    bv  = np.array([L_j-2, -L_j+1])

    # Update attributes
    att = dict(VJt.info.items() +
               {'Transform':'ISWT',
                'Type'     :'Smooth',
                'BCs'      :bv}.items())

    SJt = dwtArray(SJt, info=att)

    return SJt
Esempio n. 6
0
def swt_rot_cum_wav_svar(WJt, VJ0t, method='power'):
    """
    swt_cum_wav_svar -- Calculate cumulative sample variance of SWT wavelet coefficients.
    
     NAME
       swt_cum_wav_svar -- Calculate cumulative sample variance of 
             SWT wavelet coefficients.
    
     INPUTS
       WJt          -  JxN dwtArray of SWT wavelet coefficents
                       where N = number of time intervals
                             J = number of levels
                       they can be already rotated or not
       VJ0t         -  N dwtArray of SWT J0 scaling coefficents
                       they can be already rotated or not
       method       - variance estimate returned
                       'power' = |W^2|/N
                       'cum'   = cumulative variance
                       'cumsc' = cumulative "scaled" (see pag.189)
                       Default: 'power' 
    
     OUTPUTS
       cwsvar       -  cumulative wavelet sample variance (dwtArray).
    
     DESCRIPTION
       'cumsc' method is equivalent to the one on pag.189 of P&W .
    
     ALGORITHM
    
       cwsvar[j,t] = 1/N * sum( WJt^2 subscript(j,u+nuH_j mod N)) 
                        for t = 0,N-1 at jth level
       for j in range(J):
        rcwsvar[j,:] = cswvar[j,:] - t*cwsvarN[j]/(N-1.)
      
     SEE ALSO
       swt_cir_shift, swt
    """

    if method not in ('power', 'cum', 'cumsc'):
        raise ValueError('Valid methods are: "power", "cum" or "cumsc"')

    # check input
    if type(WJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if WJt.info['Type'] is not 'Wavelet':
        raise TypeError(
            'First input array does not contain Wavelet coefficients but {} coefficients'
            .format(WJt.info['Type']))
    if type(VJ0t) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if VJ0t.info['Type'] is not 'Scaling':
        raise TypeError(
            'Second input array does not contain Scaling coefficients but {} coefficients'
            .format(VJ0t.info['Type']))

    # get dimensions
    try:
        J, N = WJt.shape
    except ValueError:
        N = WJt.size
        J = 1
    if len(VJ0t.shape) > 1:
        raise ValueError('Only J0 level scaling coefficient should be given')

    # rotate if they are not yet aligned
    WJt, VJ0t = swt_cir_shift(
        WJt, VJ0t)  # the check for rotation is done in swt_cir_shift

    pWJt = WJt**2
    pVJ0t = VJ0t**2

    if method == 'power':
        Watt = dict(WJt.info.items() + {'Type': 'WavRotPower'}.items())
        Vatt = dict(VJ0t.info.items() + {'Type': 'ScalRotPower'}.items())
        return dwtArray(pWJt, info=Watt), dwtArray(pVJ0t, info=Vatt)

    cwsvar = np.cumsum(pWJt, axis=1) / N
    swsvar = np.cumsum(pVJ0t) / N

    if method == 'cum':
        Watt = dict(WJt.info.items() + {'Type': 'WavRotCumVar'}.items())
        Vatt = dict(VJ0t.info.items() + {'Type': 'ScalRotCumVar'}.items())
        return dwtArray(cwsvar, info=Watt), dwtArray(swsvar, info=Vatt)

    # compute rotated cumulative variance
    cwsvarN = cwsvar[:, -1]
    swsvarN = swsvar[-1]

    t = np.arange(N, dtype=np.float64)

    rcwsvar = cwsvar - t * cwsvarN[:, np.newaxis] / (N - 1)
    rswsvar = swsvar - t * swsvarN / (N - 1)

    Watt = dict(WJt.info.items() + {'Type': 'WavRotCumScVar'}.items())
    Vatt = dict(VJ0t.info.items() + {'Type': 'ScalRotCumScVar'}.items())
    return dwtArray(rcwsvar, info=Watt), dwtArray(rswsvar, info=Vatt)
Esempio n. 7
0
def swt(X, wtf='d4', nlevels='conservative', RetainVJ=False):
    """
    function swt(X, wtf='d4', nlevels='conservative', RetainVJ=False)
    
    NAME
       swt -- Compute the (partial) stationary wavelet transform (SWT).
    
    INPUTS
       X          -- set of observations 
                    (vector of length NX)
       wtf        -- (optional) wavelet transform filter name
                     (string, case-insensitve or wtf struct).
                     Default:  'd4'
       nlevels    -- (optional) maximum level J0 (integer) 
                     or method of calculating J0 (string).
                     Valid values: integer>0 or a valid method name
                     Default:  'conservative'
       RetainVJ   -- (optional) boolean flag to retain V at each
                     decomposition level
                     Default: False
    
    OUTPUTS
       WJt        -- SWT wavelet coefficents (J x NW array) dwtArray
       VJt        -- SWT scaling coefficients ((1 or J) x NW vector) dwtArray
    
    DESCRIPTION
       swt calculates the wavelet and scaling coefficients using the stationary wavelet transform (SWT).
    
       The optional input arguments have default values:
       * wtf      -- 'd4' filter
       * nlevels  -- 'convservative' --> J0 < log2( N / (L-1) + 1)
    
       The output arguments include an info attribute with metadata.
       info is a dictionary with the following fields:
       * Transform  -- name of transform ('SWT')
       * WTF        -- name of wavelet transform filter or a wtf_s struct.
       * NX         -- number of observations in original series (= length(X))
       * NW         -- number of wavelet coefficients
       * J0         -- number of levels of partial decompsition.
       * Aligned    -- Boolean flag indicating whether coefficients are aligned
                       with original series (1 = true) or not (0 = false).
       * RetainVJ -- Boolean flag indicating whether VJ scaling coefficients
                       at all levels have been retained (1= true) or not (0 = false).
    
    EXAMPLE
       WJt, VJt = swt(X, 'd4', 6)
    
    NOTES 
       pages 177-178 of P&W 
    
    SEE ALSO
       swtj, swt_filter, swt_choose_nlevels, nargerr, argterr, dwtArray
    """

    # Get a valid wavelet transform filter coefficients struct.
    wtf_s = wtfilter(wtf)

    wtfname = wtf_s.Name
    gt = wtf_s.g
    ht = wtf_s.h
    L = wtf_s.L

    # ensure X is a numpy array
    X = np.array(X)
    if len(X.shape) > 1:
        raise ValueError('SWT: Input array must be one-dimensional')
    #  N    = length of original series
    N = X.size

    #  If nlevels is an integer > 0, set J0 = nlevels.
    #  otherwise, select J0 based on choice method specified.
    if isinstance(nlevels, str):
        J0 = swt_choose_nlevels(nlevels, wtfname, N)
    elif isinstance(nlevels, int):
        if nlevels > 0:
            J0 = nlevels
        else:
            raise ValueError(
                'SWT:negativeJ0, nlevels must be an integer greater than 0.')
    else:
        raise ValueError('SWT:invalidNLevelsValue')

    if (J0 < 0):
        raise ValueError('SWT:negativeJ0')

    if (2**J0 > N):
        raise ValueError('SWT:LargeJ0',
                         'JO must be < log2(Number of samples).')

    # NW = length of the extended series = number of coefficients
    NW = X.size
    # Initialize the scale (Vin) for first level by setting it equal to X
    Vin = X
    # Pre-allocate memory.
    WJt = np.ndarray((J0, NW), dtype=np.float64) * np.nan
    if RetainVJ:
        VJt = np.ndarray((J0, NW), dtype=np.float64) * np.nan
    else:
        VJt = np.ndarray((NW), dtype=np.float64) * np.nan

    # Do the SWT.
    from swtj import swtj
    bw = np.ndarray((J0, 2)) * np.nan
    for j in range(J0):
        Wt_j, Vout = swtj(Vin, j + 1, ht, gt)
        WJt[j, :] = Wt_j
        Vin = Vout
        if RetainVJ:
            VJt[j, :] = Vout

        # boundary values 198
        L_j = equivalent_filter_width(L, j + 1)
        bw[j, 0] = min(L_j - 2, NW - 1)  #max index to the left
        #bw[j,1] = np.nan #Bc are only at the beginning
    if not RetainVJ:
        VJt[:] = Vout
        bv = bw[-1, :]
    else:
        bv = bw

    # Update attributes
    att = {
        'Transform': 'SWT',
        'WTF': wtfname,
        'N': N,
        'NW': NW,
        'J0': J0,
        'Aligned': False,
        'RetainVJ': RetainVJ,
        'Type': 'Wavelet',
        'BCs': bw
    }
    WJt = dwtArray(WJt, info=att)

    att = {
        'Transform': 'SWT',
        'WTF': wtfname,
        'N': N,
        'NW': NW,
        'J0': J0,
        'Aligned': False,
        'RetainVJ': RetainVJ,
        'Type': 'Scaling',
        'BCs': bv
    }
    VJt = dwtArray(VJt, info=att)

    return WJt, VJt
Esempio n. 8
0
def swt_cir_shift(WJt, VJ0t, subtract_mean_VJ0t=True):
    """
    shift_swt_coef -- shift the SWT wavelet and scaling coefficients.
    
    NAME
        shift_swt_coef -- Shift the SWT wavelet and scaling coefficients.

    INPUTS
        WJt          =  JxN dwtArray of SWT wavelet coefficents
                        where N = number of time intervals,
                              J = number of levels
        VJ0t         =  N dwtArray of SWT scaling coefficients at level J0.

        subtract_mean_VJ0t = (optional) subtract mean value of scaling coefficient 
                        from itself
                        Default: True

    OUTPUTS
        W  = shifted wavelet coefficients with boundary conditions (dwtArray)
        V  = shifted scaling coefficients with boundary conditions (dwtArray)
        boundaries = demarcing the circularly shifted SWT coefficients influenced 
                     by the circularity conditions
        bw  = Jx2 array with min/max indices of wavelet boundary coefficients
        bv  = Jx2 array with min/max indices of scaling boundary coefficients

    DESCRIPTION
       The SWT coefficients are circularly shifted at each level so as to 
       properly align the coefficients with the original data series. See P&W fig 183

    SEE ALSO
       swt, swt_filter
       multi_yoffset_plot
    """

    # check input
    if type(WJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if WJt.info['Type'] is not 'Wavelet':
        raise TypeError(
            'First input array does not contain Wavelet coefficients but {} coefficients'
            .format(WJt.info['Type']))
    if type(VJ0t) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if VJ0t.info['Type'] is not 'Scaling':
        raise TypeError(
            'Second input array does not contain Scaling coefficients but {} coefficients'
            .format(VJ0t.info['Type']))

    wtf_s = wtfilter(WJt.info['WTF'])
    L = wtf_s.L

    wtfname = WJt.info['WTF']
    N = WJt.info['N']
    NW = WJt.info['NW']
    J0 = WJt.info['J0']

    Nm = min(N, NW)

    if WJt.info['Aligned']:
        print(
            'WARNING (ante.swt.swt_cir_shift): Wavelet coefficients are already aligned'
        )
        W = WJt
    else:
        if WJt != dwtArray([]):
            W = np.ndarray(WJt.shape) * np.nan
            bw = np.ndarray((J0, 2)) * np.nan
            for j in range(J0):
                # shift wavelet coefficients
                nuHj = advance_wavelet_filter(wtfname, j + 1)
                W[j, :] = np.roll(WJt[j, :], nuHj)

                #Calculate circularly shifted wavelet coefficient boundary indices at jth level
                L_j = equivalent_filter_width(L, j + 1)

                bw[j, 0] = L_j - 2 - np.abs(nuHj)  #max index to the left
                bw[j, 1] = Nm - abs(nuHj)  #min index to the right
            W = W[:, :Nm]
            # Update attributes
            att = dict(WJt.info.items() + {'Aligned': True, 'BCs': bw}.items())
            W = dwtArray(W, info=att)
        else:  # if an empty array was given, do nothing and return it
            W = WJt

    if VJ0t.info['Aligned']:
        print(
            'WARNING (ante.swt.swt_cir_shift): Wavelet coefficients are already aligned'
        )
        V = VJ0t
    else:
        V = np.ndarray(VJ0t.shape) * np.nan
        bv = np.ndarray((2, )) * np.nan
        # shift scaling coefficients
        if VJ0t != dwtArray([]):
            nuGj = advance_scaling_filter(wtfname, J0)
            if subtract_mean_VJ0t:
                VJ0t = VJ0t - VJ0t.mean()
            V = np.roll(VJ0t, nuGj)

            bv[0] = L_j - 2 - np.abs(nuGj)  #max index to the left
            bv[1] = Nm - np.abs(nuGj)  #min index to the right
            # Update attributes
            att = dict(VJ0t.info.items() + {
                'Aligned': True,
                'BCs': bv
            }.items())
            V = dwtArray(V, info=att)
        else:  # if an empty array was given, do nothing and return it
            V = VJ0t

    return W, V
Esempio n. 9
0
def iswt_smooth(VJt):
    """
    iswt_smooth -- Calculate smooths at J0 level via inverse stationary wavelet transform (ISWT).

    NAME
       iswt_smooth -- Calculate smooths at J0 level via inverse stationary wavelet transform (ISWT).
    
    INPUTS
       VJt          =  N dwtArray of SWT scaling coefficients at J0 level.
    
    OUTPUT
       SJOt         =  dwtArray of reconstituted smoothed data series.
    
    DESCRIPTION
    
    EXAMPLE
       SJt = iswt_smooth(VJt)
    
    SEE ALSO
       iswtj, iswt, iswt_details, swt_filter, swt
    """

    # Get the wavelet transform filter coefficients.
    if type(VJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if VJt.info['Type'] is not 'Scaling':
        raise TypeError(
            'Input array does not contain Scaling coefficients but {} coefficients'
            .format(VJt.info['Type']))
    wtfname = VJt.info['WTF']
    J0 = VJt.info['J0']
    wtf_s = wtfilter(wtfname)
    gt = wtf_s.g
    ht = wtf_s.h
    L = wtf_s.L

    if len(VJt.shape) > 1:
        if VJt.info['RetainVJ']:
            VJt = VJt[-1, :]
        else:
            raise TypeError('The input is a multidimensional array but {} SWT\
             has been computed with RetainVJ=False. \n')
    N = VJt.size

    # initialize arrays
    zeroj = np.zeros(N)

    Vin = VJt

    #import pyximport; pyximport.install()
    from swtj import iswtj
    for j in range(J0 - 1, -1, -1):
        Vout = iswtj(zeroj, Vin, j + 1, ht, gt)
        Vin = Vout

    SJt = Vout

    # boundary values pag.199 P&W
    L_j = equivalent_filter_width(L, J0)
    bv = np.array([L_j - 2, -L_j + 1])

    # Update attributes
    att = dict(VJt.info.items() + {
        'Transform': 'ISWT',
        'Type': 'Smooth',
        'BCs': bv
    }.items())

    SJt = dwtArray(SJt, info=att)

    return SJt
Esempio n. 10
0
def iswt_details(WJt):
    """
    iswt_details -- Calculate details via inverse stationary wavelet transform (ISWT).

    NAME
       iswt_details -- Calculate details via inverse stationary wavelet transform (ISWT).
    
    INPUTS
       WJt          -  NxJ array of SWT wavelet coefficents
                       where N  = number of time points
                             J = number of levels.
                       The array must be a dwtArray (containing the information on the transform)
    
    OUTPUT
       DJt          -  JxN dwtArray of reconstituted details of data series for J0 scales.
       att          -  structure containing ISWT transform attributes.
    
    DESCRIPTION
       The output parameter att is a structure with the following fields:
           name      - name of transform (= 'SWT')
           wtfname   - name of SWT wavelet filter
           npts      - number of observations (= length(X))
           J0        - number of levels 
    
    EXAMPLE
       DJt = iswt_details(WJt)
    
    SEE ALSO
       iswtj, iswt, iswt_smooth, swt_filter, swt
    """

    # Get a the wavelet transform filter coefficients.
    if type(WJt) is not dwtArray:
        raise TypeError('Input must be a dwtArray')
    if WJt.info['Type'] is not 'Wavelet':
        raise TypeError(
            'Input array does not contain Wavelet coefficients but {} coefficients'
            .format(WJt.info['Type']))
    wtfname = WJt.info['WTF']
    wtf_s = wtfilter(wtfname)

    gt = wtf_s.g
    ht = wtf_s.h
    L = wtf_s.L

    J, N = WJt.shape
    J0 = J

    zeroj = np.zeros(N)
    DJt = np.zeros((J, N))

    from swtj import iswtj
    for j in range(J0 - 1, -1, -1):
        Vin = zeroj
        Win = WJt[j, :]
        for jj in range(j, -1, -1):
            Vout = iswtj(Win, Vin, jj + 1, ht, gt)
            Win = zeroj
            Vin = Vout
        DJt[j, :] = Vout

    # boundary values 199
    bw = np.ndarray((J0, 2), dtype=np.int16) * np.nan
    for j in range(J0):
        #Calculate wavelet coefficient boundary indices at jth level
        L_j = equivalent_filter_width(L, j + 1)
        bw[j, 0] = L_j - 2
        bw[j, 1] = -L_j + 1
    # Update attributes
    att = dict(WJt.info.items() + {
        'Transform': 'ISWT',
        'Type': 'Detail',
        'BCs': bw
    }.items())

    DJt = dwtArray(DJt, info=att)

    return DJt