我在特定矩阵乘法方面存在问题。
有没有循环的优雅方法吗?
我之前的代码无法正常运行:
[n,m] = size(x);
nn=3;
aa = [ 0.069 0.167 0.826];
bb = [ 0.132 0.302 0.917];
a = repmat(aa,[n 1]);
b = repmat(bb,[n 1]);
res = ((-x'*b)*a');
我有一个想法如何做到这一点,但我不知道如何通过放置从1到N的所有行,从(M x N)矩阵创建一行(1 x N)向量将原始矩阵转换为向量的值。 例如:
A =[1 2 3; 11 22 33; 111 222 333]
A = [[1; 11; 111]; [2; 22; 222]; [3; 33; 333]]
我发现我甚至无法初始化这样的结构。但如果有某种方法可以做到这一点,我仍然需要.*
操作才能正常工作,例如:
A = [[1; 11; 111]; [2; 22; 222]]
A.*[1 3 3]
result: A = [[1 3 3; 11 33 33; 111 333 333]; [2 6 6; 22 66 66; 222 666 666]]
答案 0 :(得分:1)
请允许我重新提出您的要求,以便适合未来的读者。
X
的每一列与b
之间的outer product。因此,对于X
的每列,每列都有M
个元素/行,我们每次都会生成一个M x 3
矩阵。对所有列进行操作将生成N
M x 3
个矩阵。具体来说,给定X
列M x 1
和b
1 x 3
列,外部产品是X
和{{1}之间的矩阵乘法因此,它为我们提供了一个b
矩阵。我们重复此M x 3
次,其中N
是矩阵中的列数。N
大小为N
的矩阵,您希望将此结果中的每个矩阵乘以M x 3
的转置,以便最终输出将是一个长度为a
的列向量,因此我们将有M
个。{/ li>
回答第2步的问题:是的,没有循环是可能的。我会permute
矩阵N
,这样我们就可以创建一个3D矩阵,其中第一个横切片就是矩阵X
本身。考虑3D体积,但体积只有1个切片,此切片是矩阵X
。该切片也横向和纵向旋转90度。如果您还需要澄清,请考虑一个精简的3D矩阵,其中X
的每列在3D矩阵中生成1个切片。每个2D切片由单个X
列组成。我需要以这种方式重塑2D矩阵的原因是我们可以轻松地计算外部产品。我是通过bsxfun
完成的。外部产品基本上可以通过从您正在处理的X
复制列并将M
向量复制到底部来计算,直到我们创建相同大小的2个矩阵。完成此操作后,您只需进行逐点乘法即可。 b
基本上会将bsxfun
向量复制到一个3D矩阵中,其中每个切片都包含该复制的b
向量,并且它会重复与矩阵中的切片一样多的切片。对于b
的3D矩阵,每个切片将其列复制到右侧,直到我们有一个与复制的X
3D矩阵具有兼容大小的3D矩阵。
因此,步骤#2可以通过以下方式优雅地计算:
b
out = bsxfun(@times, permute(X.', [2 3 1]), b);
应包含一个3D矩阵,其中每个切片out
存储矩阵i
的列M x 3
与{{}之间的结果乘法的i
矩阵1}}。
您现在希望获取这些矩阵中的每一个(存储在X
中)并使用b
的转置计算乘法。是的,你也可以没有循环,但这需要一些操作。矩阵乘法(真正的定义)仅为2D矩阵定义。 3D矩阵没有这样的定义。因此,我们必须做的是将我们的3D切片中的所有2D切片都堆叠起来,然后将它们堆叠起来,使它们形成单个2D矩阵。该2D矩阵将out
的每个a
矩阵堆叠在一起,使得该矩阵的总维度为M x 3
。一旦我们这样做,我们就可以简单地使用这个矩阵并将其乘以out
的转置。这将生成NM x 3
向量。此向量将{{1>}长度为a
的{{1}}向量全部连接在一起形成一个向量。要最终提取NM x 1
长度向量,只需N
向量,即可获得M
矩阵。现在,这个矩阵将被堆叠,使得矩阵的每个行包含您最终要搜索的向量之一。
因此:
N
最后,reshape
将包含我们所讨论的矩阵。第一个输出向量存储在N x M
中,第二个输出向量存储在[M,N] = size(X);
out2 = reshape(permute(out, [2 1 3]), [3 N*M]).';
out_vec = out2 * a.';
out_mat = reshape(out_vec, [M N]).';
中,依此类推。
希望这有帮助,祝你好运!