创建一个"金字塔"矩阵

dod*_*she 12 arrays matlab matrix

假设我给出了一个奇数长度的对称行向量,其中每个元素小于向量的前半部分中的下一个元素,并且每个元素大于下半部分中的下一个元素,中间元素是最大的.(例如[1 2 3 2 1][10 20 50 20 10]).

我想创建一个方形矩阵,其中此行向量是其中间行,等效列vector(v')是其中间列,并且每个其他行或列是给定向量的缩减版本,根据此行或列中的中间元素.当我们没有更多的"原始元素"时0.

例子:

如果v = [1 2 3 2 1]我们得到

0 0 1 0 0  
0 1 2 1 0  
1 2 3 2 1  
0 1 2 1 0  
0 0 1 0 0
Run Code Online (Sandbox Code Playgroud)

如果v = [3 5 3]我们得到

0 3 0  
3 5 3  
0 3 0  
Run Code Online (Sandbox Code Playgroud)

到目前为止我做了什么:我设法创建了一个矩阵v作为中间行和v'中间列,我写了这个代码:

s = length(vector);
matrix= zeros(s);
matrix(round(s/2),:) = vector;
matrix(:, round(s/2)) = vector';
Run Code Online (Sandbox Code Playgroud)

但是因为分配其他值而陷入困境.

Div*_*kar 8

这是一种方法 -

function out = pyramid(v)

hlen = (numel(v)+1)/2;
updown_vec = [1:(numel(v)+1)/2 (numel(v)-1)/2:-1:1];
upper_part = cumsum(bsxfun(@le,(hlen:-1:1)',updown_vec));  %//'
out = [upper_part ; flipud(upper_part(1:end-1,:))];
out = changem(out,v,updown_vec);
Run Code Online (Sandbox Code Playgroud)

这是另一种方法,可能更简单 -

function out = pyramid_v2(v)

hlen = (numel(v)+1)/2;
updown_vec = [1:(numel(v)+1)/2 (numel(v)-1)/2:-1:1];
mask = bsxfun(@le,([hlen:-1:1 2:hlen])',updown_vec); %//'
M = double(mask);
M(hlen+1:end,:) = -1;
out = changem(cumsum(M).*mask,v,updown_vec);
Run Code Online (Sandbox Code Playgroud)

样品运行 -

>> v = [1 2 3 2 1];
>> pyramid(v)
ans =
     0     0     1     0     0
     0     1     2     1     0
     1     2     3     2     1
     0     1     2     1     0
     0     0     1     0     0
>> v = [3 5 3];
>> pyramid(v)
ans =
     0     3     0
     3     5     3
     0     3     0

>> v = [99,3,78,55,78,3,99];
>> pyramid(v)
ans =
     0     0     0    99     0     0     0
     0     0    99     3    99     0     0
     0    99     3    78     3    99     0
    99     3    78    55    78     3    99
     0    99     3    78     3    99     0
     0     0    99     3    99     0     0
     0     0     0    99     0     0     0
Run Code Online (Sandbox Code Playgroud)


And*_*eak 8

更实际的方法是从hankel矩阵开始将矩阵生成为马赛克.对于性能比较,这是一个使用与@Divakar解决方案相同格式的版本:

function out=pyramid_hankel(v)

%I suggest checking v here
%it should be odd in length and a palindrome    

i0=ceil(length(v)/2);
v2=v(i0:end);

Mtmp=hankel(v2);
out=zeros(length(v));
out(i0:end,i0:end)=Mtmp;
out(1:i0-1,i0:end)=flipud(Mtmp(2:end,:));
out(:,1:i0-1)=fliplr(out(:,i0+1:end));
Run Code Online (Sandbox Code Playgroud)
>> pyramid_hankel([1 2 3 2 1])

ans =

     0     0     1     0     0
     0     1     2     1     0
     1     2     3     2     1
     0     1     2     1     0
     0     0     1     0     0
Run Code Online (Sandbox Code Playgroud)

对于v=[1 2 3 2 1]起始块hankel([3 2 1]),是

ans =

     3     2     1
     2     1     0
     1     0     0
Run Code Online (Sandbox Code Playgroud)

从这里开始,应该清楚发生了什么.


Lui*_*ndo 5

这是另一种方法:

v = [1 2 3 2 1]; %// symmetric, odd size
m = (numel(v)-1)/2;
w = [0 v(1:m+1)];
t = abs(-m:m);
result = w(max(m+2-bsxfun(@plus, t, t.'),1));
Run Code Online (Sandbox Code Playgroud)