Умножение ненулевых значений двух матриц - PullRequest
0 голосов
/ 17 марта 2020

У меня есть две матрицы, умноженные друг на друга HZ , где обе матрицы H и Z имеют одинаковый размер (256,256), Матрица Z является матрицей перестановок, имеющей следующий шаблон: В первых 32 строках только столбцы 1,9,17, ... (256-8) ненулевые, остальные столбцы нули, следующие 32 строки, только столбцы 2,10,18, ... (256-7) ненулевые, остальные столбцы нули и т. д. до последних 32 строк, где столбцы 8,16,24, ...., 256 не равны нулю, а другие столбцы - нули.

Следовательно, умножение матрицы H на Z включает только умножение первых 32 элементов первой строки в H на первый элемент 32 столбца 1 матрицы Z , затем следующий элемент 32 первых строк матрицы H со следующим элементом 32 ( 33-64 элементов) столбца 2 в матрице Z и т. Д. потому что все другие умножения будут результатом нуля. Таким образом, количество умножений будет меньше.

Мой вопрос, я не мог написать это в Matlab !! Я не знаю, как создать l oop to go только через ненулевые элементы. Не могли бы вы помочь в этом?

Заранее спасибо.

1 Ответ

2 голосов
/ 17 марта 2020

Для циклов обычно намного медленнее, чем встроенные операции 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

Результаты по времени:

f1 - 6.875835e-05 s
f2 - 0.0008205853 s

К сожалению, новый подход примерно в 12 раз медленнее, чем простое умножение матриц. Это связано с тем, что MATLAB сильно оптимизирован для умножения матриц, а умножение полных матриц H и Z обеспечивает непрерывную работу используемой памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...