コード例 #1
0
ファイル: Wavelet.py プロジェクト: kingjml/pySnowRadar
def cwt(data, wavelet, scales, precision):
    '''
    Implementation of the Continuous Wavelet Transform

    Arguments:
        data: preprocessed snowradar signal data
        wavelet: the specific Wavelet to use (currently the Haar wavelet)
        scales: 
        precision: precision to apply to wavelet operations (default 10)

    Outputs:
        out_coefs:(?)
    '''
    out_coefs = np.zeros((np.size(scales), data.size))
    int_psi, x = pywt.integrate_wavelet(wavelet, precision=precision)
    step = x[1] - x[0]
    x_step = (x[-1] - x[0]) + 1

    j_a = [np.arange(scale * x_step) / (scale * step) for scale in scales]
    j_m = [
        np.delete(j,
                  np.where((j >= np.size(int_psi)))[0]) for j in j_a
        if np.max(j) >= np.size(int_psi)
    ]
    coef_a = [
        -np.sqrt(scales[i]) *
        np.diff(np.convolve(data, int_psi[x.astype(np.int)][::-1]))
        for (i, x) in enumerate(j_m)
    ]
    out_coefs = np.asarray([
        coef[int(np.floor((coef.size - data.size) /
                          2)):int(-np.ceil((coef.size - data.size) / 2))]
        for coef in coef_a
    ])
    return out_coefs
コード例 #2
0
def test_intwave_orthogonal():
    w = pywt.Wavelet('db1')
    int_psi, x = pywt.integrate_wavelet(w, precision=12)
    ix = x < 0.5
    # For x < 0.5, the integral is equal to x
    assert_allclose(int_psi[ix], x[ix])
    # For x > 0.5, the integral is equal to (1 - x)
    # Ignore last point here, there x > 1 and something goes wrong
    assert_allclose(int_psi[~ix][:-1], 1 - x[~ix][:-1], atol=1e-10)
コード例 #3
0
ファイル: utils.py プロジェクト: wuwenbo718/Master-Thesis
def cwt_tf(data, scales, wavelet, batch_size, sampling_period=1.):

    # accept array_like input; make a copy to ensure a contiguous array
    dt = tf.float32
    dt_cplx = tf.complex64
    if not isinstance(wavelet, (pywt.ContinuousWavelet, pywt.Wavelet)):
        wavelet = pywt.DiscreteContinuousWavelet(wavelet)
    if np.isscalar(scales):
        scales = np.array([scales])

    dt_out = dt_cplx if wavelet.complex_cwt else dt
    out = []
    precision = 10
    int_psi, x = pywt.integrate_wavelet(wavelet, precision=precision)
    int_psi = np.conj(int_psi) if wavelet.complex_cwt else int_psi

    # convert int_psi, x to the same precision as the data
    dt_psi = np.complex64 if int_psi.dtype.kind == 'c' else np.float32
    int_psi = np.asarray(int_psi, dtype=dt_psi)
    x = np.asarray(x, dtype=np.float32)

    for i, scale in enumerate(scales):
        step = x[1] - x[0]
        j = np.arange(scale * (x[-1] - x[0]) + 1) / (scale * step)
        j = j.astype(int)  # floor
        if j[-1] >= int_psi.size:
            j = np.extract(j < int_psi.size, j)
        int_psi_scale = int_psi[j][::-1]
        int_psi_scale_n = np.zeros(
            (len(int_psi_scale), data.shape[-1], data.shape[-1]),
            dtype=int_psi_scale.dtype)
        for c in range(data.shape[-1]):
            int_psi_scale_n[:, c, c] = int_psi_scale

        conv = tf.nn.convolution(data, int_psi_scale_n, 1, 'SAME')

        coef = -tf.math.sqrt(float(scale)) * tf.experimental.numpy.diff(
            conv, axis=-2)

        if dt_out != dt_cplx:
            coef = tf.math.real(coef)

        out += [tf.cast(tf.abs(coef), dt_out)]

#     frequencies = pywt.scale2frequency(wavelet, scales, precision)
#     if np.isscalar(frequencies):
#         frequencies = np.array([frequencies])
#     frequencies /= sampling_period
    return tf.transpose(tf.convert_to_tensor(out, dtype=dt_out),
                        (1, 0, 2, 3))  #, frequencies
コード例 #4
0
def Continuous_Wavelet_Transform(X,
                                 scales,
                                 sample_rate=500,
                                 wavelet=None,
                                 use_scipy_signal=True,
                                 *a,
                                 **k):
    '''
    Unforturnately it's a very misleading terminology here to name it by
    Continuous Wavelet Transform. Actually, in engineering, both cwt and
    dwt are digital, point-by-point transform algorithums that can easily
    implemented on a computer. If two mathematicians talk about CWT, it
    really mean Continuous-WT. But here, CWT just misleading people.

    A cwt is a discret operation as well as dwt. The difference is how they
    convolve signal with wavelet. CWT will convolve signal with wavelet
    moveing foreward point-by-point while DWT moves window-by-window. When
    decomposition level grows, wavelet need to be expanded in length. CWT
    wavelet length will be 2, 3, 4, 5, ... and DWT will be 2, 4, 8, ...
    '''
    # check params
    if np.isscalar(scales):
        scales = np.arange(1, scales + 1)
    scales = np.array(scales)
    assert 0 not in scales
    if not use_scipy_signal and wavelet not in pywt.wavelist():
        wavelet = 'morl'

    # prepare wavelets
    if use_scipy_signal:
        wavelets = [
            wavelet(min(10 * scale, X.shape[1]), scale) for scale in scales
        ]
    else:
        int_psi, x = pywt.integrate_wavelet(wavelet, precision=10)
        wavelets = []
        for scale in scales:
            j = np.arange(scale * (x[-1] - x[0]) + 1)
            j = np.floor(j / scale / (x[1] - x[0]))
            wavelets.append(int_psi[np.int32(j[j < len(int_psi)])][::-1])

    # convolve
    coef = np.array([[np.convolve(ch, w, mode='same') for w in wavelets]
                     for ch in X])
    if use_scipy_signal:
        freq = None
    else:
        coef = -np.sqrt(scales).reshape(len(scales), 1) * np.diff(coef)
        freq = (pywt.central_frequency(wavelet, 10) / scales * sample_rate)
    return coef, freq
コード例 #5
0
def child_wav(wavelet, scale):
    """Returns an array of complex values with the child wavelet used at the
    given ``scale``.

    The ``wavelet`` argument can be either a string like 'cmor1-1.5' or
    a ``pywt.ContinuousWavelet`` instance
    """

    wavelet = _wavelet_instance(wavelet)

    # the following code has been extracted from pywt.cwt() 1.0.2
    precision = 10
    int_psi, x = pywt.integrate_wavelet(wavelet, precision=precision)
    step = x[1] - x[0]
    j = np.floor(np.arange(scale * (x[-1] - x[0]) + 1) / (scale * step))
    if np.max(j) >= np.size(int_psi):
        j = np.delete(j, np.where((j >= np.size(int_psi)))[0])

    return int_psi[j.astype(np.int)]
コード例 #6
0
ファイル: cwt_scaling_demo.py プロジェクト: zhang-yuanye/pywt
# print the range over which the wavelet will be evaluated
print("Continuous wavelet will be evaluated over the range [{}, {}]".format(
    wav.lower_bound, wav.upper_bound))

width = wav.upper_bound - wav.lower_bound

scales = [1, 2, 3, 4, 10, 15]

max_len = int(np.max(scales) * width + 1)
t = np.arange(max_len)
fig, axes = plt.subplots(len(scales), 2, figsize=(12, 6))
for n, scale in enumerate(scales):

    # The following code is adapted from the internals of cwt
    int_psi, x = pywt.integrate_wavelet(wav, precision=10)
    step = x[1] - x[0]
    j = np.floor(np.arange(scale * width + 1) / (scale * step))
    if np.max(j) >= np.size(int_psi):
        j = np.delete(j, np.where((j >= np.size(int_psi)))[0])
    j = j.astype(np.int_)

    # normalize int_psi for easier plotting
    int_psi /= np.abs(int_psi).max()

    # discrete samples of the integrated wavelet
    filt = int_psi[j][::-1]

    # The CWT consists of convolution of filt with the signal at this scale
    # Here we plot this discrete convolution kernel at each scale.
コード例 #7
0
def test_continuous_wavelet_dtype(dtype):
    wavelet = pywt.ContinuousWavelet('cmor1.5-1.0', dtype)
    int_psi, x = pywt.integrate_wavelet(wavelet)
    assert int_psi.real.dtype == dtype
    assert x.dtype == dtype
コード例 #8
0
ファイル: cwt_scaling_demo.py プロジェクト: PyWavelets/pywt
# print the range over which the wavelet will be evaluated
print("Continuous wavelet will be evaluated over the range [{}, {}]".format(
    wav.lower_bound, wav.upper_bound))

width = wav.upper_bound - wav.lower_bound

scales = [1, 2, 3, 4, 10, 15]

max_len = int(np.max(scales)*width + 1)
t = np.arange(max_len)
fig, axes = plt.subplots(len(scales), 2, figsize=(12, 6))
for n, scale in enumerate(scales):

    # The following code is adapted from the internals of cwt
    int_psi, x = pywt.integrate_wavelet(wav, precision=10)
    step = x[1] - x[0]
    j = np.floor(
        np.arange(scale * width + 1) / (scale * step))
    if np.max(j) >= np.size(int_psi):
        j = np.delete(j, np.where((j >= np.size(int_psi)))[0])
    j = j.astype(np.int)

    # normalize int_psi for easier plotting
    int_psi /= np.abs(int_psi).max()

    # discrete samples of the integrated wavelet
    filt = int_psi[j][::-1]

    # The CWT consists of convolution of filt with the signal at this scale
    # Here we plot this discrete convolution kernel at each scale.
コード例 #9
0
def fastcwt(data, scales, wavelet, sampling_period=1.0, method='auto'):
    """
    Compute the continuous wavelet transform (CWT) and has the same signature
    as ``pywt.cwt()`` but is faster for large signals length and scales.

    Parameters
    ----------
    signal : array to compute the CWT on
    
    scales: dilatation factors for the CWT
    
    wavelet: wavelet name or pywt.ContinuousWavelet

    method=['auto'] | 'conv' | 'fft' for selecting the convolution method
        the `'auto'` keyword switch automatically to the best complexity at each
        scales. While the `'fft'` and `'conv'` uses `numpy.fft` and `numpy.conv`
        respectively.

    In practice the `'fft'` method is implemented by using the convolution 
    theorem which states::
        convolve(wav,sig) == ifft(fft(wav)*fft(sig))

    Zero padding is adjusted to keep at bay circular convolution side effects.


    Example::

        %time (coef1, freq1) = fastcwt(np.arange(140000), np.arange(2,200), 'cmorl1-1')
        => CPU times: user 12.6 s, sys: 2.2 s, total: 14.8 s
        => Wall time: 14.9 s

        %time (coef1, freq1) = pywt.cwt(np.arange(140000), np.arange(2,200), 'cmorl1-1')
        => CPU times: user 1min 50s, sys: 401 ms, total: 1min 51s
        => Wall time: 1min 51s
    """

    # accept array_like input; make a copy to ensure a contiguous array
    data = np.array(data)
    if not isinstance(wavelet, (pywt.ContinuousWavelet, pywt.Wavelet)):
        wavelet = pywt.DiscreteContinuousWavelet(wavelet)
    if np.isscalar(scales):
        scales = np.array([scales])
    dt_out = None  # currently keep the 1.0.2 behaviour: TODO fix in/out dtype consistency
    if data.ndim == 1:
        if wavelet.complex_cwt:
            dt_out = complex
        out = np.zeros((np.size(scales), data.size), dtype=dt_out)
        precision = 10
        int_psi, x = pywt.integrate_wavelet(wavelet, precision=precision)

        if method in ('auto', 'fft'):
            # - to be as large as the sum of data length and and maximum wavelet
            #   support to avoid circular convolution effects
            # - additional padding to reach a power of 2 for CPU-optimal FFT
            size_pad = lambda s: 2**np.int(np.ceil(np.log2(s[0] + s[1])))
            size_scale0 = size_pad(
                (len(data), np.take(scales, 0) * ((x[-1] - x[0]) + 1)))
            fft_data = None
        elif not method == 'conv':
            raise ValueError("method must be in: 'conv', 'fft' or 'auto'")

        for i in np.arange(np.size(scales)):
            step = x[1] - x[0]
            j = np.floor(
                np.arange(scales[i] * (x[-1] - x[0]) + 1) / (scales[i] * step))
            if np.max(j) >= np.size(int_psi):
                j = np.delete(j, np.where((j >= np.size(int_psi)))[0])
            int_psi_scale = int_psi[j.astype(np.int)][::-1]

            if method == 'conv':
                conv = np.convolve(data, int_psi_scale)
            else:
                size_scale = size_pad((len(data), len(int_psi_scale)))
                if size_scale != size_scale0:
                    # the fft of data changes when padding size changes thus
                    # it has to be recomputed
                    fft_data = None
                size_scale0 = size_scale
                nops_conv = len(data) * len(int_psi_scale)
                nops_fft = (
                    2 + (fft_data is None)) * size_scale * np.log2(size_scale)
                if (method == 'fft') or ((method == 'auto') and
                                         (nops_fft < nops_conv)):
                    if fft_data is None:
                        fft_data = np.fft.fft(data, size_scale)
                    fft_wav = np.fft.fft(int_psi_scale, size_scale)
                    conv = np.fft.ifft(fft_wav * fft_data)
                    conv = conv[0:len(data) + len(int_psi_scale) - 1]
                else:
                    conv = np.convolve(data, int_psi_scale)

            coef = -np.sqrt(scales[i]) * np.diff(conv)
            if not np.iscomplexobj(out):
                coef = np.real(coef)
            d = (coef.size - data.size) / 2.
            if d > 0:
                out[i, :] = coef[int(np.floor(d)):int(-np.ceil(d))]
            elif d == 0.:
                out[i, :] = coef
            else:
                raise ValueError("Selected scale of {} too small.".format(
                    scales[i]))
        frequencies = pywt.scale2frequency(wavelet, scales, precision)
        if np.isscalar(frequencies):
            frequencies = np.array([frequencies])
        for i in np.arange(len(frequencies)):
            frequencies[i] /= sampling_period
        return out, frequencies
    else:
        raise ValueError("Only dim == 1 supported")
コード例 #10
0
The wavelet transform of a time series $y(t)$ is given by:

$\begin{align} WT(y(t)) = \frac{1}{\sqrt{|\sigma|}}\int_{-\infty}^{\infty}y(t)\psi \left( \frac{t-h}{\sigma} \right)dt \end{align}$

where $\sigma$ is the scale, $h$ is the time lag/translation, and $\psi$ is the mother wavelet. 

From the WT, we obtaing sets of coefficients corresponding to different time lags and scales. The greater the magnitude of the coefficients, the greater overlap there is between the scaled, time-shifted mother wavelet and the time series.

def rescale(arr, scale=2):
    n = len(arr)
    return np.interp(np.linspace(0, n, scale*n+1), np.arange(n), arr)

fig, ax = plt.subplots(figsize=(15, 2))
wav1 = pywt.ContinuousWavelet('gaus1')
int_psi1, x = pywt.integrate_wavelet(wav1)
for s in range(5):
    ax.plot(rescale(int_psi1, scale=s), label='Scale: '+ str(s))
    ax.legend()
    ax.set_title('Gaussian Mother Wavelet')

Suppose we have a signal of repearing Gaussian waves. Applying the WT on this signal using a mother wavelet corresponding to that of a Gaussian wavelet, we can pinpoint where the time series exhibits a Gaussian-like pattern.

s1 = list(scp.signal.gaussian(250, std=20))
s1 = np.tile(s1, 4)
plt.subplots(figsize=(15, 2))
plt.xlim(left=0, right=1000)
plt.ylabel('Value')
plt.xlabel('Time (t)')
plt.plot(s1)
plt.show()