Alter number sort / number sequence

Viewed 62

I have an array / number sequence a=[1,2,3,4,5] and I'm trying to create an array / number sequence that looks like a_new below: The columns represent the orders / index the numbers should go in.

a_new=...
[1,2,3,4,5;
2,1,2,3,4;
3,3,1,2,3;
4,4,4,1,2;
5,5,5,5,1]

My thoughts where to use circshift but quickly found out that would not work.

a=[1,2,3,4,5];
for n=1:5
  a_wrong(:,n)=circshift(a(:)',[0 n])(:)
end

produces

a_wrong=[
    5   4   3   2   1
    1   5   4   3   2
    2   1   5   4   3
    3   2   1   5   4
    4   3   2   1   5]

Any thoughts? It doesn't need to use circshift if that won't work.

PS: I'm using Octave 4.2 which is similar to Matlab

3 Answers

There are probably quite a few different ways to generate this matrix. Here's one using the functions repmat, toeplitz, tril, and triu:

>> a_new = tril(repmat(a.', 1, numel(a)), -1)+triu(toeplitz(a))

a_new =

     1     2     3     4     5
     2     1     2     3     4
     3     3     1     2     3
     4     4     4     1     2
     5     5     5     5     1

I'm not sure about a built-in function, but this should work;

a=[1,2,3,4,5];
a_out = ones(length(a), length(a))
for n=1:5
    a_out(n,:) = [n*ones(n-1),a(n:end)]
end

I do not have Octave or MATLAB installed on my computer, so I cannot test it. This may have a silly error, forgive me for that!

You can use spdiags to generate the matrix:

n = numel(a);    
a_new = spdiags([repmat(flip(a).',1,n); repmat(a,n-1,1)],(1-n):0);
Related