Изменение диагоналей матрицы с помощью Mathematica
есть ли элегантный способ изменить диагонали матрицы на новый список значений, эквивалент группы с SparseArray?
скажем, у меня есть следующая матрица (см. ниже)
(mat = Array[Subscript[a, ##] &, {4, 4}]) // MatrixForm
и я хотел бы изменить основную диагональ на следующую, чтобы получить "новый коврик" (см. ниже)
newMainDiagList = Flatten@Array[Subscript[new, ##] &, {1, 4}]
Я знаю, что легко изменить основную диагональ на заданное значение с помощью ReplacePart. Например:
ReplacePart[mat, {i_, i_} -> 0]
Я также хотел бы не быть ограниченным на главной диагонали (точно так же, как группа не так ограничена SparseArray)
(метод, который я использую в данный момент, следующий!)
(Normal@SparseArray[Band[{1, 1}] -> newMainDiagList] +
ReplacePart[mat, {i_, i_} -> 0]) // MatrixForm
(желаемый выход - "новый коврик")
1 ответов
на самом деле, вам не нужно использовать Normal
вообще. А SparseArray
плюс "нормальная" матрица дает вам "нормальную" матрицу. Используя Band
является, при первоначальной проверке, наиболее гибким подходом, но эффективной (и немного менее гибкой) альтернативой является:
DiagonalMatrix[newDiagList] + ReplacePart[mat, {i_,i_}->0]
DiagonalMatrix
также принимает второй целочисленный параметр, который позволяет указать, какая диагональ newDiagList
представляет с главной диагональю, представленной 0.
наиболее элегантной альтернативой, однако, является использование ReplacePart
немного более эффективно: замена Rule
может быть RuleDelayed
, например,
ReplacePart[mat, {i_,i_} :> newDiagList[[i]] ]
что делает вашу замену сразу без промежуточных шагов.
редактировать: для того чтобы передразнить Band
поведение, мы также можем добавить условия к шаблону через /;
. Например,
ReplacePart[mat, {i_,j_} /; j==i+1 :> newDiagList[[i]]
заменяет диагональ непосредственно над главный (Band[{1,2}]
), и
ReplacePart[mat, {i_,i_} /; i>2 :> newDiagList[[i]]
заменит только последние два элемента главной диагонали в 4x4
матрица (Band[{3,3}]
). Но, это намного проще, используя ReplacePart
напрямую.