我想创建一个矩阵,其中中间对角线对称地减少到两侧,如下所示:
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;
答案 0 :(得分:7)
要查找矢量化解决方案,请考虑使用spdiags()
。
n = 5;
A = repmat([1:n-1,n:-1:1],n,1);
B = full(spdiags(A,-n+1:n-1,n,n));
这将返回:
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之间。
答案 1 :(得分:6)
我很惊讶没有人向您推荐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
答案 2 :(得分:5)
一些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
答案 3 :(得分:4)
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)
绘制结果: