OverLordGoldDragon / ssqueezepy

Synchrosqueezing, wavelet transforms, and time-frequency analysis in Python
MIT License
647 stars 95 forks source link

torch.as_tensor( ) does not support tensor with negative strindes #115

Closed Kaysen-Zhao closed 5 days ago

Kaysen-Zhao commented 6 days ago

Description

Hello, thanks for your wonderful work!

When I use ssqueezepy to execute wavelet transform and its inversion on a batch time series data with shape(batch, length), it reported error as follows.

I finally find that it is the reason that torch.as_tensor( ) does not support tensor with negative strides.

The environment that I used: torch==1.9.0+cu102 cupy==10.6.0 numpy==1.24.4

I modified astray( ) function in backend.py to solve this problem

def asarray(x, dtype=None, device='cuda'):
    if USE_GPU():
        if(isinstance(x, np.ndarray)):
            return torch.as_tensor(x.copy(), dtype=_torch_dtype(dtype), device=device)
        return torch.as_tensor(x, dtype=_torch_dtype(dtype), device=device)
    return np.asarray(x, dtype=dtype)

Error info:

    high_energy_time = icwt(mask_Wx, wavelet=self.wavelet, scales=scales, one_int=True)
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/_cwt.py", line 440, in icwt
    Cpsi = (adm_ssq(wavelet) if one_int else
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/cwt_utils.py", line 45, in adm_ssq
    Css = integrate_analytic(lambda w: np.conj(asnumpy(wavelet(w))) / w)
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/cwt_utils.py", line 626, in integrate_analytic
    arr, t = _find_convergent_array()
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/cwt_utils.py", line 602, in _find_convergent_array
    arr, t, min_neglect_idx = _est_arr(mxlim, N=10000*m)
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/cwt_utils.py", line 592, in _est_arr
    arr = int_fn(t)
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/cwt_utils.py", line 45, in <lambda>
    Css = integrate_analytic(lambda w: np.conj(asnumpy(wavelet(w))) / w)
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/_gmw.py", line 201, in <lambda>
    return lambda w: fn(S.atleast_1d(w, dtype), gamma, beta, wc, wcl)
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/backend.py", line 59, in atleast_1d
    return Q.atleast_1d(asarray(x, dtype=dtype, device=device))
  File "/data/zkx/miniconda3/envs/Linear2/lib/python3.9/site-packages/ssqueezepy/utils/backend.py", line 32, in asarray
    return torch.tensor(x, dtype=_torch_dtype(dtype), device=device)
ValueError: At least one stride in the given numpy array is negative, and tensors with negative strides are not currently supported. (You can probably work around this by making a copy of your array  with array.copy().)

Code for reproduction

import torch
import os
from ssqueezepy import cwt,icwt

os.environ['SSQ_GPU']='1'

data = torch.randn((256, 1024), dtype=torch.float32)
wavelet  = ('morlet', {'mu': 20})

Wx, scales = cwt(data, wavelet=wavelet, padtype='zero')
energy = torch.abs(Wx) ** 2
normalized_energy = energy / energy.max()
high_energy_mask = normalized_energy > 0.5
mask_Wx = torch.where(high_energy_mask, Wx, torch.zeros_like(Wx))

high_energy_time = icwt(mask_Wx, wavelet=wavelet, scales=scales, one_int=True)
OverLordGoldDragon commented 5 days ago

Interesting this stuck around so long. This and another problem. But no silent failures.

Thanks for the report, fixed.