用矩阵乘法克服尺寸误差?

时间:2015-03-20 23:00:10

标签: python arrays numpy matrix

我希望将两个矩阵相乘(要清楚我想要它在线性代数中的含义,即,如果你想进一步澄清我的意思,请参阅Wikipedia article)I&# 39;我试过A * B(我在Scipy Wiki跟随MATLAB到Numpy指南得到了)但A的维度为(N-1)x(N-1)和{ {1}}的维度为(N-1)x(N + 1),它给出了ValueError(其中B):

N=100

我也试过ValueError: operands could not be broadcast together with shapes (99,99) (99,101) 以防我无意中使用数组(ps。可能就是这种情况,因为我对我构建A和B的向量有一些np.asarray命令。如何做我把它们转换成矩阵?)而不是矩阵并得到相同的结果。

这是我的完整代码(授予的A和B分别由np.dot(A,B)np.diag(xasub)替换,这位于np.sin...行)

d2Tsub

2 个答案:

答案 0 :(得分:1)

我用以下内容复制了您的MATLAB代码:

N = 100.
n = np.arange(N+1).reshape(1,-1)
x = np.cos(np.pi*n/N).T
xsub = x[1:-1,:]
T = np.cos(np.arccos(x)*n)  # broadcasted outer product
Tsub = T[1:-1,:]
dT = np.dot(np.sin(np.arccos(x)*n), np.diag(n.flat))
# np.diag needs 1d input to generate 2d array
# this is a case of matrix multiplication, the np.dot for array
# * for np.matrix

继续

temp = np.dot(np.diag(xsub.flat), np.sin(np.arccos(xsub)*n))
temp = np.dot(Tsub, np.diag(n.flat)) - temp
temp = np.dot(temp, np.diag(n.flat))
d2Tsub = np.dot(np.diag((1/np.sqrt(1-xsub**2)).flat), temp))
凌乱,但运行并生成匹配值。使用这些数组的np.matrix版本可能会简化外观,就像清理重复的np.diag(...flat)一样。

对于d2T的其余部分,此vstack是一个非常直接的翻译。

d2T1 = ((-1)**n) * (n**2-1) * (n**2)/3
d2T2 = (n**2-1) * (n**2)/3
d2T = np.vstack([d2T1, d2Tsub, d2T2])

最后一步是矩阵划分。 MATLAB有两个版本:

D2 = np.linalg.solve(T, d2T)        # matlab T\d2T
D2 = np.linalg.solve(T.T, d2T.T).T  # matlab d2T/T

我从Y/XX\Y的八度文档中找出了最后一个等价词。

这是字面翻译。我不是想了解发生了什么,或者说它是惯用的numpy


部分简化。不需要矩阵产品使用对角矩阵。简单(广播)元素乘法就足够了。

n = np.arange(N+1)
x = np.cos(np.pi*n/N)[:,None]
Xn = np.arccos(x)*n
T = np.cos(Xn)
dT = np.sin(Xn)*n

xsub = x[1:-1,:]
d2Tsub = ((1-xsub**2)**(-.5)) * (T[1:-1,:] * n - xsub * np.sin(Xn[1:-1,:]))
d2T2 = (n**2-1) * (n**2)/3
d2T1 = ((-1)**n) * d2T2

你可以用diag(n)*代替matlab中的很多n.*例如

dT = n.*sin(acos(x)*n);  # equals
dT = sin(acos(x)*n)*diag(n);

然而,我在Octave测试了这个,现在有广播。我不确定MATLAB在这方面的立场。

答案 1 :(得分:0)

实际上,你有所有数组和没有矩阵:

xasub : <type 'numpy.ndarray'>
xc    : <type 'numpy.ndarray'>
xa    : <type 'numpy.ndarray'>
xmin  : <type 'int'>
LA    : <type 'module'>
na    : <type 'numpy.ndarray'>
nd    : <type 'numpy.ndarray'>
Tsub  : <type 'numpy.ndarray'>
np    : <type 'module'>
pi    : <type 'float'>
dTsub : <type 'numpy.ndarray'>
N     : <type 'int'>
T     : <type 'numpy.ndarray'>
sp    : <type 'module'>
xcsub : <type 'numpy.ndarray'>
n     : <type 'list'>
xmax  : <type 'int'>
x     : <type 'numpy.ndarray'>
dT    : <type 'numpy.ndarray'>

因此,您需要相应地修改最后一行以使用np.dot()(使用可怕的变量名称):

#d2Tsub = np.diag(np.power((xasub*xasub-1),-1)) * (Tsub*nd - np.diag(xasub) * np.sin(np.outer(np.arccos(xasub),nd)))*nd * nd
d2T_1  = np.diag(np.power((xasub*xasub-1),-1))
d2T_2  = np.dot( np.diag(xasub), np.sin(np.outer(np.arccos(xasub),nd)) )

d2T_3  = np.dot(d2T_1, (Tsub*nd - d2T_2))

d2Tsub = np.dot(d2T_3, nd)

print d2Tsub.shape  # (99L,)

当然,您可以使用a.dot(b)语法代替np.dot(a,b)并节省一点点空间。