Простой расчет для всех комбинаций (перебор) элементов в двух массивах, для повышения производительности, в Julia

#arrays #julia #combinations

Вопрос:

Я новичок в Джулии (некоторый опыт работы с Python). Основная причина, по которой я начинаю использовать Julia, заключается в повышении производительности для крупномасштабной обработки данных.

Я хочу получить различия значений (int) всех возможных комбинаций в двух массивах.

Допустим, у меня есть два массива.

a = [5,4]
b = [2,1,3]

Тогда я хочу иметь различия всех комбинаций, таких как a[1] — b[1], a[1] — b[2]….. a[3] — b[1], a[3] — b[2]

Результатом будет массив 3 x2 [3 2; 4 3; 2 1]

Затем я кое-что придумал:

 a = [5,4]  
b = [2,1,3]
diff_matrix = zeros(Int8, size(b)[1], size(a)[1])
for ia in eachindex(a)
    for ib in eachindex(b)
        diff_matrix[ib,ia]= a[ia] - b[ib]
    end
end
println(diff_matrix)
 

Это работает, но он использует итерацию внутри итерации, и я предполагаю, что производительность будет невелика. В реальном приложении длина массива будет большой (например, несколько сотен), и этот процесс необходимо выполнить для миллионов комбинаций массивов.

Существует ли какой-либо лучший (лучшая производительность, более простой код) подход к этой задаче ?

Ответ №1:

Если бы вы завернули код в функцию, ваш код был бы уже достаточно быстрым.

В этом как раз и заключается сила Джулии в том, что петли получаются быстрыми. Единственное, чего вам нужно избегать, — это использовать глобальные переменные в вычислениях (поскольку они приводят к коду, который не является стабильным по типу).

Я пишу код» достаточно быстро», так как его можно было бы ускорить с помощью некоторых низкоуровневых трюков. Однако в этом случае вы могли бы просто написать:

 julia> a = [5,4]                
2-element Vector{Int64}:        
 5                              
 4                              
                                
julia> b = [2,1,3]              
3-element Vector{Int64}:        
 2                              
 1                              
 3                              
                                
julia> permutedims(a) .- b      
3×2 Matrix{Int64}:              
 3  2                           
 4  3                           
 2  1                           
 

и этот код будет быстрым (и намного проще в качестве бонуса).

Комментарии:

1. Здорово. Ваш код намного проще и работает идеально. Кроме того, действительно полезно знать, как избегать глобальных переменных, так как я только начал Джулию.