On Wed, Jan 24, 2024 at 6:29 AM Fabio Matti <somecallmefa...@gmail.com>
wrote:

> Hi,
>
> In the `numpy.polynomial.chebyshev` module, the function for raising a
> Chebyshev polynomial to a power, `chebpow` [1], is essentially implemented
> in the following way:
>
> {{{#!highlight python
> def chebpow(c, pow):
>     """Raise a Chebyshev series to a power."""
>         zs = _cseries_to_zseries(c)
>         prd = zs
>         for i in range(2, pow + 1):
>             prd = np.convolve(prd, zs)
>         return _zseries_to_cseries(prd)
> }}}
>
> For large coefficient arrays `c` and big exponents `pow`, this procedure
> is not efficient. In fact, the complexity of this function is
> `O(pow*len(c)^2)`, since the numpy convolution does not make use of a Fast
> Fourier Transform (FFT).
>
> It is known that Chebyshev polynomials can be multiplied with Discrete
> Cosine Transforms (DCT) [2]. What results is the following
> algorithm`O(pow*len(c)*log(pow*len(c)))` algorithm for raising a Chebyshev
> polynomial with coefficients `c` to an integer power:
>
> {{{#!highlight python
> def chebpow_dct(c, pow):
>     """Raise a Chebyshev series to a power."""
>         pad_length = (pow - 1) * (len(c) - 1)
>         c = np.pad(c, (0, pad_length))
>         c[1:-1] /= 2
>         c_pow = idct(dct(c) ** pow)
>         c_pow[1:-1] *= 2
>         return c_pow
> }}}
>
> The only issue I am having is that as far as I know, `numpy` (unlike
> `scipy`) does not have a specialized implementation for the DCT. So the
> only way of getting the code to work is "emulating" a DCT with two calls to
> `numpy.fft.rfft`, which is slightly slower than  using the `scipy.fft.dct`.
>
> I have created a Google colab notebook which compares the error and
> runtime of the different implementations (current implementation,
> implementation using `scipy.fft.dct`, and pure numpy implementation) [3].
> Especially for larger degree polynomials and higher powers this enhancement
> would make a huge difference in terms of runtime.
>
> Similarly, `chebmul` and `chebinterpolate` can also be implemented more
> efficiently by using a DCT.
>
> Do you think this enhancement is worth pursuing, and should I create a
> pull-request for it?
>
> Best,
>
> Fabio
>
> [1]
> https://github.com/numpy/numpy/blob/main/numpy/polynomial/chebyshev.py#L817
> [2] https://www.sciencedirect.com/science/article/pii/0024379595006966
> [3]
> https://colab.research.google.com/drive/1JtDDeWC1CEQHDidZ9f5_Ma_ifoBv4Tuz?usp=sharing


This is a tricky sort of decision. The various polynomial functions were
designed so that they could be used with different types, Fractions, for
instance, and for degrees less than about 50 max. They are sort of a cross
between teaching tools and quick prototyping. I agree that for fast
production code and big degrees, DCT is the way to go for Chebyshev. There
are even some packages out there designed on that basis. I wouldn't
complain if someone produced a package with restricted types that was more
efficient than what NumPy has, indeed, types are already restricted for
curve fitting. NumPy is trending towards specialization these days, I
suspect a separate polynomial package would be a better place for such
improvements.

Chuck
_______________________________________________
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com

Reply via email to