как насчет простого цикла?
function change_diagonal!(A)
@inbounds for i = 1:size(A,1)
if iseven(A[i,i])
A[i,i] = 3*A[i,i]
else
A[i,i] = A[i,i]/2
end
end
return A
end
Одна проблема с этим заключается в том, что ваша матрица имеет тип Int64, и деление нечетного числа на два не дает целого числа. но, в общем, если вы хотите выполнить операцию только над основными элементами плотной матрицы, простой цикл будет простым и быстрым. важно отметить, что это изменяет матрицу на месте, поэтому при выполнении операции не выделяется никакой памяти. Если мы расширим это, чтобы сделать его более общим:
function change_diagonal!(f,A)
@inbounds for i = 1:size(A,1)
A[i,i] = f(A[i,i])
end
return A
end
Вы можете передать любую функцию иэта функция будет отображаться на диагональных элементах вашей матрицы.
РЕДАКТИРОВАТЬ: есть другой способ, я не знаю, если быстрее (вероятно, нет), но ради полноты, здесь егоИдея: вы можете сгенерировать вектор, который соответствует виду диагонали матрицы, поэтому при изменении этого вектора вы изменяете исходную матрицу. вот функция, которая генерирует это представление:
function diagonal_view(A)
return @view A[diagind(A)]
end
теперь вы можете работать с диагональю, как если бы это был простой вектор:
A = rand(1.0:10.0,5,5)
diagA = diagonal_view(A)
diagA .= 40.0 #all elements of the diagonal of A are changed to 40.0
map!(x->2x,diagA,diagA) # another way to modify the diagonal, doubles the values