More windows for filtering and spectral analysis
Labels: triaged, module: scipy compatibility

### 🚀 The feature, motivation and pitch

#### Introduction

This feature request looks to add more windows for filtering and spectral analysis. I've noticed that we're supporting only the following windows:

- `barlett_window`
- `blackman_window`
- `hamming_window`
- `hann_window`
- `kaiser_window`

But there are many more windows that are pretty useful. For instance, the Dolph-Chebyshev window which optimizes for the minimum main lobe width for a given side-lobe specification.

So, I'm proposing we add the following windows:

- [ ] `chebyshev_window`
- [ ] `taylor_window`
- [x] `cosine_window`
- [x] `gaussian_window`
- [x] `exponential_window`
- [ ] `kbd_window`
- [x] `nutall_window`

We could add more to the list.

#### Motivation

One of the things I came across is filtering signals when trying to create custom datasets. The window function that I tried to use was Dolph-Chebyshev, but PyTorch does not support it at the moment. Other functions such as Kaiser-Bessel Derived window function is broadly used in audio signal processing.

### Alternatives

The solutions are quite straightforward.

From the list of proposed windows, the most complex one is the Dolph-Chebyshev window which requires an inverse FFT. But this is easy to apply as the IFFT implementation exists in PyTorch already. This window would require creating CUDA and CPU kernels. I already have an implementation that I could share in a draft PR if this feature is accepted.

The other window functions are quite simple and easy to implement, namely, the cosine window, exponential window, and gaussian window. I also have implementations for these.

A sneak peek of the CPU `chebyshev_window_kernel`:

This calculates the window coefficients in the frequency domain. The IFFT would be applied after the call to the kernel's finished.

```cpp
static void chebyshev_window_kernel(TensorIteratorBase& iter, int64_t window_length, double attenuation) {
  AT_DISPATCH_FLOATING_TYPES_AND(kBFloat16, iter.dtype(), "chebyshev_window_cpu", [&](){
    const int64_t n = window_length - 1;
    const scalar_t beta = static_cast<scalar_t>(std::cosh(1.0 / n * std::acosh(std::pow(10, attenuation / 20.0))));
    cpu_kernel(iter, [=](scalar_t a){
      auto x = beta * static_cast<scalar_t>(std::cos(c10::pi<double> * a / window_length));
      return static_cast<scalar_t>(chebyshev_polynomial_t_forward(x, n) / std::pow(10, attenuation / 20.0));
    });
  });
}
```

And for the `cosine_window` function:

Does not need a kernel, I believe.

```cpp
Tensor cosine_window(
    int64_t window_length,
    bool periodic,
    c10::optional<ScalarType> dtype_opt,
    c10::optional<Layout> layout,
    c10::optional<Device> device,
    c10::optional<bool> pin_memory) {
  // See [Note: hacky wrapper removal for TensorOptions]
  ScalarType dtype = c10::dtype_or_default(dtype_opt);
  TensorOptions options = TensorOptions().dtype(dtype).layout(layout).device(device).pinned_memory(pin_memory);

  window_function_checks("cosine_window", options, window_length);
  if (window_length == 0) {
    return at::empty({0}, options);
  }
  if (window_length == 1) {
    return native::ones({1}, dtype, layout, device, pin_memory);
  }
  if (periodic) {
    window_length += 1;
  }
  auto window = native::arange(window_length, dtype, layout, device, pin_memory)
                    .add(0.5).mul_(c10::pi<double>).mul_(static_cast<double>(1.0 / window_length)).sin_();
  return periodic ? window.narrow(0, 0, window_length - 1) : window;
}
```

The other window functions would follow the same or similar approach.

### Additional context

#### References

- Window functions:
   - https://sites.google.com/site/stevedtran/course/intro-to-digital-signal-processing/notes2/windowing/type-of-windowing

- Kaiser-Bessel Derived Window:
    - Bosi, Marina, and Richard E. Goldberg. Introduction to Digital Audio Coding and Standards. Dordrecht: Kluwer, 2003.

- Dolph-Chebyshev Window:
    - https://ccrma.stanford.edu/~jos/sasp/Dolph_Chebyshev_Window.html

- Taylor Window:
    - Armin Doerry, "Catalog of Window Taper Functions for
           Sidelobe Control", 2017 https://www.researchgate.net/profile/Armin_Doerry/publication/316281181_Catalog_of_Window_Taper_Functions_for_Sidelobe_Control/links/58f92cb2a6fdccb121c9d54d/Catalog-of-Window-Taper-Functions-for-Sidelobe-Control.pdf

- Nutall Window:
    - A. Nuttall, “Some windows with very good sidelobe behavior,” IEEE Transactions on Acoustics, Speech, and Signal Processing, vol. 29, no. 1, pp. 84-91, Feb 1981. [DOI:10.1109/TASSP.1981.1163506](https://doi.org/10.1109/TASSP.1981.1163506)