【问题标题】:Multiplying non-zeros values of two matrices将两个矩阵的非零值相乘
【发布时间】:2020-06-28 04:46:23
【问题描述】:

我有两个矩阵相乘 HZ 其中两个矩阵 HZ 的大小相同 (256,256) 。矩阵 Z 是置换矩阵,具有以下模式:在前 32 行中,只有列 1,9,17,...(256-8) 是非零,其他列是零,接下来 32 行,只有列 2,10,18,...(256-7) 是非零,其他列为零,依此类推,直到最后 32 行,其中列 8,16,24,....,256 为非零,其他列是零。

因此,将矩阵HZ相乘仅包括将H中第一行的前32个元素相乘矩阵 Z 的第 1 列的第一个 32 元素,然后是矩阵 H 第一行的下一个 32 个元素,下一个 32Z2列的/em>元素(33-64元素)等等。因为所有其他乘法将导致零。所以那样的话,乘法的次数会更少。

我的问题,我不能在 Matlab 中写出来!我不知道如何创建循环以仅通过非零元素。你能帮忙吗?

提前谢谢你。

【问题讨论】:

  • 过早的优化是万恶之源。只需对所有元素使用正常的元素乘法。仅循环通过非零条目的效率要低得多
  • @SardarUsama 感谢您的回复。是的,这就是我需要做的?循环遍历 Z 的非零条目。我该怎么做?
  • “因此,矩阵 H 与 Z 相乘仅包含”...所以您是说 H*Z 会产生正确的结果,但您试图跳过 nzero 个?
  • 你可以通过find(any(M,2))获取非零元素的切片,其中2决定方向,即是列还是行
  • @Daniel 是的,正是……这就是我的意思

标签: matlab


【解决方案1】:

For 循环通常比内置的 MATLAB 操作慢得多。更好的选择是使用以下方法仅乘以 Z 的非零元素。

result = zeros(256,256);
result(Z ~= 0) = H(Z ~= 0) .* Z(Z ~= 0);

您可以在下面看到完整的代码,运行测试以确保它得到正确的答案,并为代码计时以查看它是否更快。

% setup variables
H = rand(256,256);
Z = zeros(256,256);
for i = 1:8
    Z((i-1)*32+1:i*32, i:8:256) = 1;
end

% run calcuations and check that they are equal
HZ1 = f1(H, Z);
HZ2 = f2(H, Z);
are_equal = all(all(HZ1 == HZ2));

% time both functions
timeit(@() f1(H,Z))
timeit(@() f2(H,Z))

function result = f1(H, Z)
    result = H .* Z;
end
function result = f2(H, Z)
    result = zeros(256,256);
    result(Z ~= 0) = H(Z ~= 0) .* Z(Z ~= 0);
end

Timeit 结果:

f1 - 6.875835e-05 s
f2 - 0.0008205853 s

不幸的是,新方法比仅将矩阵逐元素相乘慢了大约 12 倍。这是因为 MATLAB 针对矩阵乘法进行了高度优化,将完整的矩阵 HZ 相乘可确保要操作的内存是连续的。

【讨论】:

    猜你喜欢
    • 2015-04-01
    • 1970-01-01
    • 2014-10-30
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多