Подтвердить что ты не робот

Каков рекомендуемый способ перебора матрицы по строкам?

Учитывая матрицу m = [10i+j for i=1:3, j=1:4], я могу перебирать ее строки, нарезая матрицу:

for i=1:size(m,1)
    print(m[i,:])
end

Это единственная возможность? Это рекомендуемый способ?

А как насчет понимания? Разрезает единственную возможность итерации по строкам матрицы?

[ sum(m[i,:]) for i=1:size(m,1) ]
4b9b3361

Ответ 1

Решение, которое вы указали сами, а также mapslices, отлично работает. Но если "рекомендуется", что вы действительно имеете в виду, это "высокопроизводительный", тогда лучший ответ: не перебирайте строки.

Проблема заключается в том, что поскольку массивы хранятся в основном порядке столбцов, для чего-либо другого, кроме маленькой матрицы, вы получите плохое отношение кэш-памяти, если вы перемещаете массив в строчном порядке.

Как указано в отличном сообщении в блоге, если вы хотите суммировать по строкам, лучше всего сделать что-то вроде этого:

msum = zeros(eltype(m), size(m, 1))
for j = 1:size(m,2)
    for i = 1:size(m,1)
        msum[i] += m[i,j]
    end
end

Мы перемещаем как m, так и msum в свой собственный порядок хранения, поэтому каждый раз, когда мы загружаем строку кеша, мы используем все значения, что дает коэффициент попадания в кэш 1. Вы можете наивно думать, что лучше пройти его в строчном порядке и накапливать результат в переменную tmp, но на любой современной машине промах кэша намного дороже, чем поиск msum[i].

Многие внутренние алгоритмы Julia, которые принимают параметр region, например sum(m, 2), обрабатывают это для вас.

Ответ 2

Согласно моим опытам, явные итерации намного быстрее, чем понимание.

Итерация по столбцам также является хорошим советом.

Кроме того, вы можете использовать новые макросы @simd и @inbounds для дальнейшего ускорения.