Add Support for Polynomial-Polynomial Multiplication in the Newton Basis
In extending Minterpy capabilities to carry out polynomial algebra, we should add polynomial-polynomial multiplication in the Newton basis. Basically, we would like to define the following operation
>>> nwt_poly_1
<minterpy.polynomials.newton_polynomial.NewtonPolynomial at 0x17f6bc460>
>>> nwt_poly_2
<minterpy.polynomials.newton_polynomial.NewtonPolynomial at 0x17f6bc5b0>
>>> nwt_poly_1 * nwt_poly_2
<minterpy.polynomials.newton_polynomial.NewtonPolynomial at 0x15ef3be80>
and
>>> nwt_poly_1 *= nwt_poly_2
<minterpy.polynomials.newton_polynomial.NewtonPolynomial at 0x15ef3be80>
Currently, only polynomials in the Lagrange basis may be multiplied with a polynomial in the Lagrange basis (though the later is still carried out inconsistently; a separate issue will be opened).
Here are the steps to carry out the multiplication:
- Create a product of the two multi-index sets
- Create a grid of the union multi-index set
- Compute the value at the unisolvent nodes
- Multiply the values together (they become the Lagrange coefficients)
- Do a DDS on the Lagrange coefficients to obtain the Newton coefficients
- Create a new instance of Newton polynomial with the new multi-index set and coefficients
These steps, especially the detour via Lagrange coefficients, are required because the Newton basis depends on the underlying interpolation grid (mainly the degree) of the polynomials even if they're the same generating function.
This means the Newton polynomial basis of the 3rd-degree for a polynomial of degree 4 using the Leja-ordered Chebyshev-Lobatto nodes is (because the nodes are, in this order, 1, -1, 0, and 0.5): (x - 1) (x + 1) (x - 0)
while the same basis for a polynomial of degree 3 using the same nodes is (because the nodes are, in this order, 1, -1, 0.5): (x - 1) (x + 1) (x - 0.5)
These two bases are not the same even if both are Chebyshev-Lobatto nodes.
Several things to consider so the implementation would be consistent:
- Multiplication of a polynomial with a constant polynomial should give an equivalent result with the multiplication of a polynomial with a real scalar number.
- Only polynomials with a matching domain can be multiplied
- Only polynomials with the same generating function can be multiplied (no such attribute yet)
- Only left-sided (default) multiplication needs to be implemented; right-sided multiplication (
__rmul__()
) would never got called if two instances are both polynomials. If the left term is a scalar, an implementation is already in-place. - Augmented multiplication should be supported, updating all the properties (
MultiIndexSet
,Grid
, andcoeffs
) of the left-hand side.
This issue is part of the improvement of Minterpy for polynomial algebraic manipulations (see Issue #142 (closed)).