Создайте матрицу "пирамида"
Скажем, мне задан симметричный вектор строки с нечетной длиной, где каждый элемент меньше, чем следующий в первой половине вектора, и каждый элемент больше, чем следующий во второй половине, а средний элемент - самый большой. (например, [1 2 3 2 1]
или [10 20 50 20 10]
).
Я хочу создать квадратную матрицу, где этот вектор строки является ее средней строкой, а эквивалентный вектор столбца (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
если v = [3 5 3]
получаем
0 3 0
3 5 3
0 3 0
Что я сделал до сих пор: мне удалось создать матрицу с v
в качестве средней строки и v'
в качестве среднего столбца с этим кодом, который я написал:
s = length(vector);
matrix= zeros(s);
matrix(round(s/2),:) = vector;
matrix(:, round(s/2)) = vector';
но застрял в назначении других значений.
Ответы
Ответ 1
Более практичный подход состоит в том, чтобы создать вашу матрицу как мозаику, начиная с матрицы hankel
. Для сравнения производительности здесь версия, использующая тот же формат, что и @Divakar solution:
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));
>> 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
Для v=[1 2 3 2 1]
стартовый блок hankel([3 2 1])
, который
ans =
3 2 1
2 1 0
1 0 0
Отсюда должно быть ясно, что происходит.
Ответ 2
Здесь один подход -
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);
Здесь другой подход, вроде более простой -
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);
Примеры прогона -
>> 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
Ответ 3
Здесь другой подход:
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));