Reputation: 1637
Is there a quick way to change the diagonals beside the center diagonal (referring to the 1
s below):
m =
2 1 0 0 0 0 0 0 0
1 2 1 0 0 0 0 0 0
0 1 2 1 0 0 0 0 0
0 0 1 2 1 0 0 0 0
0 0 0 1 2 1 0 0 0
0 0 0 0 1 2 1 0 0
0 0 0 0 0 1 2 1 0
0 0 0 0 0 0 1 2 1
0 0 0 0 0 0 0 1 2
A quick way to change the center diagonal is m(logical(eye(size(m)))) = 2
. How about assigning the diagonals beside it to values of 1
?
Upvotes: 0
Views: 428
Reputation: 45741
The diag
function takes a second parameter, k
, which specifies which diagonal to target:
diag([-1,-1,-1,-1],-1) % or diag(-1*ones(4,1),1)
ans =
0 0 0 0 0
-1 0 0 0 0
0 -1 0 0 0
0 0 -1 0 0
0 0 0 -1 0
diag([1,1,1,1],1)
ans =
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
0 0 0 0 0
diag([2,2,2],2)
ans =
0 0 2 0 0
0 0 0 2 0
0 0 0 0 2
0 0 0 0 0
0 0 0 0 0
If you already have an existing matrix and you want to change one of the diagonals you could do this:
M = magic(5) % example matrix
v = [1,2,3,4] % example vector that must replace the first diagonal of M, i.e. the diagonal one element above the main diagonal
M - diag(diag(M,1),1) + diag(v,1)
The idea is to first use diag
to extract the numbers of the diagonal you want to change, diag(M,1)
. Then to use diag
again to change the vector that the first call to diag
created into a matrix, diag(diag(M,1),1)
. You'll notice that this creates a matrix with the same dimensions as M
, the same numbers as M
on the 1st diagonal and 0
s everywhere else. Thus M - diag(diag(M,1),1)
just sets that first diagonal to 0
. Now diag(v,1)
creates a matrix with the same dimensions as M
that is 0
everywhere but with the numbers of v
on the first diagonal and so adding diag(v,1)
only affects that first diagonal which is all 0
s thanks to -diag(diag(M,1),1)
An alternative if you are just applying a constant to a diagonal (for example setting all the values on the first diagonal below the main diagonal to 6
):
n = 5;
k = -1;
a = 6;
M = magic(n);
ind = diag(true(n-abs(k),1),k);
M(ind) = a;
Upvotes: 2