Изменить диагональ неквадратной матрицы

Предположим, у меня есть такая матрица:

1 2 3
3 2 3
4 5 6
7 8 9
3 2 3

Как мне добавить диагональ единиц в это? Есть ли простой способ? Чтобы показать, что я имею в виду:

1 2 3
3 1 3
4 5 1
1 8 9
3 1 3

person Paulinchen2    schedule 14.11.2013    source источник
comment
значит, вы имеете в виду «заменить», а не операцию +, верно?   -  person Autonomous    schedule 14.11.2013


Ответы (4)


Вы можете легко сделать это с помощью линейного индексирования, вам даже не нужно изменять форму!

[r, c] = size(m);
m(1:c:end) = 1;
m =

     1     2     3
     4     1     6
     7     8     1
     1    11    12
    13     1    15

Если r < c, это лучшее, что у меня есть:

if r < c
   n = m';
   n(1:r:end) = 1;
   m = n';
else
   m(1:c:end) = 1;
end
person Stewie Griffin    schedule 14.11.2013
comment
@jkshah: Честно говоря, я не могу найти способ сделать это и избежать if, используя только линейную индексацию. Я обновил ответ. Если у вас есть предложение получше, стреляйте! знак равно - person Stewie Griffin; 15.11.2013
comment
@РобертП. +1. кажется идеальным! У меня не было лучшего решения, но я пытался сделать его полным. Цените свое мышление. - person jkshah; 15.11.2013
comment
@РобертП. Вам даже не нужен номер строки: почему бы не просто m(1:size(m,2):end) = 1? Обратите внимание, однако, что ваше решение работает только для r ›= c - person Luis Mendo; 15.11.2013

Это общее решение с использованием линейной индексации и операций по модулю:

[R C] = size(m);
ii = 1:R;
jj = mod(ii,C);
jj(jj==0) = C;
m(ii+(jj-1)*R) = 1; %// or m(sub2ind([R C],ii,jj)) = 1;

Например,

m =

     1     2     3
     4     5     6
     7     8     9
    10    11    12
    13    14    15
    16    17    18
    19    20    21

превращается в

m =

     1     2     3
     4     1     6
     7     8     1
     1    11    12
    13     1    15
    16    17     1
     1    20    21
person Luis Mendo    schedule 14.11.2013

Если вам нужна более короткая версия без сравнения количества строк с количеством столбцов, вы можете попробовать это (предположим, что вы хотите сделать диагональные элементы произвольной матрицы M равными 1):

M(logical(speye(size(M)))) = 1 
person Chris    schedule 16.11.2013

person    schedule
comment
Я попробовал это на m=[1,2,3;4,5,6;7,8,9;10,11,12;13,14,15], но была заменена только верхняя диагональ. - person Paulinchen2; 14.11.2013