强制乘法使用__rmul __()而不是Numpy数组__mul __()或绕过广播 [英] Forcing multiplication to use __rmul__() instead of Numpy array __mul__() or bypassing the broadcasting

查看:84
本文介绍了强制乘法使用__rmul __()而不是Numpy数组__mul __()或绕过广播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题与您的课程的其他__rmul__覆盖的问题相近. __mul__ ,但我的印象是,这是一个比数字数据更普遍的问题.同样也没有得到答案,我真的不想在此操作中使用矩阵乘法@.因此,这个问题.

This question is close to what is asked in Overriding other __rmul__ with your class's __mul__ but I am under the impression that this is a more general problem then only numerical data. Also that is not answered and I really don't want to use the matrix multiplication @ for this operation. Hence, the question.

我确实有一个接受标量和数值数组相乘的对象.与往常一样,左侧乘法效果很好,因为使用的是myobj()方法,但是在右侧乘法中,NumPy使用广播规则,并使用dtype=object给出元素的结果.

I do have an object which accepts multiplication with scalars and numerical arrays. As usual, the left multiplication works fine since it is the myobj() methods are used but in the right multiplication, NumPy uses broadcasting rules and gives elementwise results with dtype=object.

这还有一个副作用,即无法检查数组的大小是否兼容.

This has also the side-effect of not being able to check the size of the array whether the size is compatible or not.

因此,问题是

是否有一种方法可以强制numpy数组查找其他对象的__rmul__()而不是广播并逐元素执行__mul__()?

Is there a way to force numpy array to look for the __rmul__() of the other object instead of broadcasting and performing elementwise __mul__()?

在我的特定情况下,对象是MIMO(多输入,多输出)传递函数矩阵(如果需要,也可以是滤波器系数矩阵),因此矩阵相乘在线性系统的加法和乘法方面具有特殊含义.因此,在每个条目中都有SISO系统.

In my particular case, the object is a MIMO (multiple-input, multiple-output) transfer function matrix (or filter coefficients matrix if you will) so matrix multiplication has a special meaning in terms of adding and multiplying linear systems. Hence in each entry there is SISO system.

import numpy as np

class myobj():
    def __init__(self):
        pass

    def __mul__(self, other):
        if isinstance(other, type(np.array([0.]))):
            if other.size == 1:
                print('Scalar multiplication')
            else:
                print('Multiplication of arrays')

    def __rmul__(self, other):
        if isinstance(other, type(np.array([0.]))):
            if other.size == 1:
                print('Scalar multiplication')
            else:
                print('Multiplication of arrays')

A = myobj()
a = np.array([[[1+1j]]])  # some generic scalar
B = np.random.rand(3, 3)

使用这些定义,以下命令显示了不良行为.

With these definitions, the following commands show the undesired behavior.

In [123]: A*a
Scalar multiplication

In [124]: a*A
Out[124]: array([[[None]]], dtype=object)

In [125]: B*A
Out[125]: 
array([[None, None, None],
       [None, None, None],
       [None, None, None]], dtype=object)

In [126]: A*B
Multiplication of arrays

In [127]: 5 * A

In [128]: A.__rmul__(B)  # This is the desired behavior for B*A
Multiplication of arrays

推荐答案

默认情况下,NumPy假定未知对象(不是从ndarray继承)是标量,并且需要对所有NumPy数组的每个元素进行向量化"乘法.

By default, NumPy assumes that unknown object (not inheriting from ndarray) are scalars, and it needs to "vectorize" multiplication over each element of any NumPy arrays.

要自己控制操作,您需要设置__array_priority__(大多数向后兼容)或__array_ufunc__(仅适用于NumPy 1.13+).例如:

To control the operations yourself, you need to set either __array_priority__ (most backwards compatible) or __array_ufunc__ (NumPy 1.13+ only). For example:

class myworkingobj(myobj):
    __array_priority__ = 1000

A = myworkingobj()
B = np.random.rand(3, 3)
B * A  # Multiplication of arrays

这篇关于强制乘法使用__rmul __()而不是Numpy数组__mul __()或绕过广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆