对多个数组做矩阵乘法运算

numpy_dot.py

本习题的程序文件

NumPy数组的乘法运算符是对每个元素进行乘积的运算,而dot()则实现矩阵乘积。遗憾的是dot()只能对两个矩阵进行运算,因此计算多个矩阵连乘的语句会比麻烦,例如下面是计算\mathbf{a} \cdot \mathbf{b} \cdot \mathbf{c} \cdot \mathbf{d}的程序:

from numpy import dot
dot(dot(dot(a,b),c),d)

连乘

使用Python的内置函数reduce(),很容易编写对任意多个矩阵进行连乘的函数。请编写矩阵连乘函数mdotl():

import numpy as np
from numpy import dot

def mdotl(*args):
    "左结合律的矩阵连乘函数"
    【你的程序】

np.random.seed(0)
a,b,c,d = [np.random.rand(3,3) for i in xrange(4)]
print np.all(dot(dot(dot(a,b),c),d)==mdotl(a,b,c,d))
在定义函数时,使用带“*”的参数可以接收所有的参数。使用内置的reduce(func, seq),可以用二元函数func依次对序列seq中的两个元素进行运算。

下面是使用带“*”的参数的例子:

>>> def print_args(*args):
...     print args
...
>>> print_args(1,2,3,4)
(1, 2, 3, 4)

下面是使用reduce()的例子,首先定义一个二元函数add(x,y),然后用reduce()计算序列[1,2,3,4]的和,这相当于调用了:add(add(add(1,2),3),4):

>>> def add(x,y):
...     return x+y
...
>>> reduce(add, [1,2,3,4])
10

实际上也可以不自己定义add(),而从operator模块载入:

from operator import add

矩阵的乘法不满足交换律,因此有时我们需要计算\mathbf{a} \cdot (\mathbf{b} \cdot (\mathbf{c} \cdot \mathbf{d}))的值。请编写右结合律的矩阵连乘函数mdotr():

def mdotr(*args):
    "右结合律的矩阵连乘函数"
    【你的程序】

print np.all(dot(a, dot(b, dot(c,d)))==mdotr(a,b,c,d))

控制运算顺序

为了控制乘法运算的顺序,我们可以用元组表示乘法的顺序,例如:\mathbf{a} \cdot (\mathbf{b} \cdot \mathbf{c}) \cdot \mathbf{d},可以用mdot(a, (b,c), d)计算,请编写程序实现mdot函数。

def mdot(*args):
    "计算任意顺序的矩阵乘法函数"
    【你的程序】

print np.all(dot(dot(dot(a,b),c),d)==mdot(a,b,c,d))
print np.all(dot(a, dot(b, dot(c,d)))==mdot(a,(b,(c,d))))
print np.all(dot(dot(a, dot(b, c)), d)==mdot(a,(b,c),d))
print np.all(dot(dot(a,b),dot(c,d))==mdot((a,b),(c,d)))
print np.all(dot(dot(a,dot(b,b)),dot(c,d))==mdot((a,(b,b)),(c,d)))
mdot()需要支持任意多层嵌套,因此可以考虑使用递归算法实现。
你能只用一行代码实现mdot()的计算吗?

內容目录

上一个主题

用argmin(a)的返回值作下标存取数组

下一个主题

分析电机编码器的A相和Z相波形

本页

loading...