Matlab递减矩阵对角线
Matlab decreasing matrix diagonal
我想创建一个中间对角线向两侧对称递减的矩阵,如下所示:
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
矩阵必须为 100x100,值介于 0
和 1
之间。
到现在我只得到边缘和中间对角线,但不知道如何自动填充其余部分。
v = ones(1,100);
green = diag(v);
green(:,1) = fliplr(0:1/99:1);
green(1,:) = fliplr(0:1/99:1);
green(100,:) = 0:1/99:1;
green(:,100) = 0:1/99:1;
N = 100; %// size of your matrix
v = ones(1,N); %// get a vector of ones
D = N*diag(v); %// set the main diagonal
for ii = 1:size(D,1)-1
tmp = (N-ii)*diag(v(1:end-ii),ii); %//positive direction off-
tmp2 = (N-ii)*diag(v(1:end-ii),-ii); %//negative direction off-diagonal
D = D+tmp+tmp2; %// Add them up
end
D = D/N; %// scale values to between 0 and 1
这里的技巧是使用索引变量ii
作为同时减少乘法N-ii
的计数器,减少v
的长度,v(1:end-ii)
] 并在 diag
、ii
或 -ii
.
范围内增加对角线的偏移量
只是为了验证使用 imagesc(D)
:
绘制结果
要寻找矢量化解决方案,请考虑使用 spdiags()
。
n = 5;
A = repmat([1:n-1,n:-1:1],n,1);
B = full(spdiags(A,-n+1:n-1,n,n));
这将 return:
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
正如 @Adriaan 指出的那样 B = B/n
将在 0 和 1 之间变换矩阵值。
一些怎么样 code-golfing
-
n = 5
M = mod(bsxfun(@plus,n:-1:1,(0:n-1)'),n)
out = triu(M)+tril(n-M)
对于您的实际情况,由于您需要 [0,1]
范围内的值,您可以缩放 out
,就像这样 -
out = (out - 1)/max(out(:)-1)
样本运行-
>> n = 5;
M = mod(bsxfun(@plus,n:-1:1,(0:n-1)'),n);
out = triu(M)+tril(n-M);
>> out
out =
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
>> out = (out - 1)/max(out(:)-1)
out =
1 0.75 0.5 0.25 0
0.75 1 0.75 0.5 0.25
0.5 0.75 1 0.75 0.5
0.25 0.5 0.75 1 0.75
0 0.25 0.5 0.75 1
我很惊讶没有人向您推荐 toeplitz
矩阵:
n = 5;
out = toeplitz(n:-1:1);
我们得到:
out =
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
如果您想将其规范化为 [0,1]
,只需进行标准规范化即可:
out_new = (out - 1) / (n - 1)
...等等:
>> out = (out - 1) / (n - 1)
out =
1.0000 0.7500 0.5000 0.2500 0
0.7500 1.0000 0.7500 0.5000 0.2500
0.5000 0.7500 1.0000 0.7500 0.5000
0.2500 0.5000 0.7500 1.0000 0.7500
0 0.2500 0.5000 0.7500 1.0000
我想创建一个中间对角线向两侧对称递减的矩阵,如下所示:
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
矩阵必须为 100x100,值介于 0
和 1
之间。
到现在我只得到边缘和中间对角线,但不知道如何自动填充其余部分。
v = ones(1,100);
green = diag(v);
green(:,1) = fliplr(0:1/99:1);
green(1,:) = fliplr(0:1/99:1);
green(100,:) = 0:1/99:1;
green(:,100) = 0:1/99:1;
N = 100; %// size of your matrix
v = ones(1,N); %// get a vector of ones
D = N*diag(v); %// set the main diagonal
for ii = 1:size(D,1)-1
tmp = (N-ii)*diag(v(1:end-ii),ii); %//positive direction off-
tmp2 = (N-ii)*diag(v(1:end-ii),-ii); %//negative direction off-diagonal
D = D+tmp+tmp2; %// Add them up
end
D = D/N; %// scale values to between 0 and 1
这里的技巧是使用索引变量ii
作为同时减少乘法N-ii
的计数器,减少v
的长度,v(1:end-ii)
] 并在 diag
、ii
或 -ii
.
只是为了验证使用 imagesc(D)
:
要寻找矢量化解决方案,请考虑使用 spdiags()
。
n = 5;
A = repmat([1:n-1,n:-1:1],n,1);
B = full(spdiags(A,-n+1:n-1,n,n));
这将 return:
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
正如 @Adriaan 指出的那样 B = B/n
将在 0 和 1 之间变换矩阵值。
一些怎么样 code-golfing
-
n = 5
M = mod(bsxfun(@plus,n:-1:1,(0:n-1)'),n)
out = triu(M)+tril(n-M)
对于您的实际情况,由于您需要 [0,1]
范围内的值,您可以缩放 out
,就像这样 -
out = (out - 1)/max(out(:)-1)
样本运行-
>> n = 5;
M = mod(bsxfun(@plus,n:-1:1,(0:n-1)'),n);
out = triu(M)+tril(n-M);
>> out
out =
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
>> out = (out - 1)/max(out(:)-1)
out =
1 0.75 0.5 0.25 0
0.75 1 0.75 0.5 0.25
0.5 0.75 1 0.75 0.5
0.25 0.5 0.75 1 0.75
0 0.25 0.5 0.75 1
我很惊讶没有人向您推荐 toeplitz
矩阵:
n = 5;
out = toeplitz(n:-1:1);
我们得到:
out =
5 4 3 2 1
4 5 4 3 2
3 4 5 4 3
2 3 4 5 4
1 2 3 4 5
如果您想将其规范化为 [0,1]
,只需进行标准规范化即可:
out_new = (out - 1) / (n - 1)
...等等:
>> out = (out - 1) / (n - 1)
out =
1.0000 0.7500 0.5000 0.2500 0
0.7500 1.0000 0.7500 0.5000 0.2500
0.5000 0.7500 1.0000 0.7500 0.5000
0.2500 0.5000 0.7500 1.0000 0.7500
0 0.2500 0.5000 0.7500 1.0000