Source code for numpoly.array_function.multiply

"""Multiply arguments element-wise."""
from __future__ import annotations
from typing import Any, Optional

import numpy
import numpy.typing
import numpoly

from ..baseclass import ndpoly, PolyLike
from ..dispatch import implements


[docs]@implements(numpy.multiply) def multiply( x1: PolyLike, x2: PolyLike, out: Optional[ndpoly] = None, where: numpy.typing.ArrayLike = True, **kwargs: Any, ) -> ndpoly: """ Multiply arguments element-wise. Args: x1, x2: Input arrays to be multiplied. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which becomes the shape of the output). out: A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or `None`, a freshly-allocated array is returned. A tuple (possible only as a keyword argument) must have length equal to the number of outputs. where: This condition is broadcast over the input. At locations where the condition is True, the `out` array will be set to the ufunc result. Elsewhere, the `out` array will retain its original value. Note that if an uninitialized `out` array is created via the default ``out=None``, locations within it where the condition is False will remain uninitialized. kwargs: Keyword args passed to numpy.ufunc. Return: The product of `x1` and `x2`, element-wise. This is a scalar if both `x1` and `x2` are scalars. Example: >>> poly = numpy.arange(9.0).reshape((3, 3)) >>> q0q1q2 = numpoly.variable(3) >>> numpoly.multiply(poly, q0q1q2) polynomial([[0.0, q1, 2.0*q2], [3.0*q0, 4.0*q1, 5.0*q2], [6.0*q0, 7.0*q1, 8.0*q2]]) """ x1, x2 = numpoly.align_indeterminants(x1, x2) dtype = numpy.result_type(x1, x2) shape = numpy.broadcast_shapes(x1.shape, x2.shape) where = numpy.asarray(where) exponents = numpy.unique( numpy.tile(x1.exponents, (len(x2.exponents), 1)) + numpy.repeat(x2.exponents, len(x1.exponents), 0), axis=0, ) out_ = ( numpoly.ndpoly( exponents=exponents, shape=shape, names=x1.indeterminants, dtype=dtype, ) if out is None else out ) seen = set() for expon1, coeff1 in zip(x1.exponents, x1.coefficients): for expon2, coeff2 in zip(x2.exponents, x2.coefficients): key = (expon1 + expon2 + x1.KEY_OFFSET).ravel() key = key.view(f"U{len(expon1)}").item() if key in seen: out_.values[key] += numpy.multiply( coeff1, coeff2, where=where, **kwargs ) else: numpy.multiply( coeff1, coeff2, out=out_.values[key], where=where, **kwargs ) seen.add(key) if out is None: out_ = numpoly.clean_attributes(out_) return out_