# I have a vector like x=[2 3 1 5],how could I generate a vector like [1 2 1 2 3 1 1 2 3 4 5]?

1 visualizzazione (ultimi 30 giorni)
xiyou fu il 17 Set 2016
Commentato: David Goodmanson il 19 Set 2016
I have a vector like x=[2 3 1 5],how could I generate a vector like [1 2 1 2 3 1 1 2 3 4 5]?
##### 0 CommentiMostra -2 commenti meno recentiNascondi -2 commenti meno recenti

Accedi per commentare.

### Risposta accettata

David Goodmanson il 18 Set 2016
Assuming the rule you want is what Teja thought, then if you have room for a couple of arrays that could get pretty large depending on your data, you could try
m = max(x);
n = length(x);
A = repmat((1:m)',1,n); % columns of consecutive integers
M = repmat(x,m,1); % rows of copies of x
A(A>M) = nan;
A = A(:); % concatenate columns
A(isnan(A)) = []; % keep good ones
A = A';
For x of length 1e7 with random entries from 1 to 10, this takes about 5 sec on my PC.
##### 2 CommentiMostra NessunoNascondi Nessuno
xiyou fu il 18 Set 2016
It seems to work well in my case, thanks!
David Goodmanson il 19 Set 2016
You're welcome. I should point out that since the numerical calculation here is simple, for a very large problem of this type you could gain speed and save memory by declaring variables to be unsigned integers such as uint8 or uint16, whatever is compatible with the entries in vector x. Uints do not support NaN, but you can use zero as an indicator instead. In the example I used, with uint8 the speed goes up by a factor of 2.5 and the memory is reduced by a factor of 8.

Accedi per commentare.

### Più risposte (3)

Teja Muppirala il 17 Set 2016
x = [2 3 1 5]
y = arrayfun(@(a)1:a,x,'uniform',0)
y = cat(2,y{:})
y = 1 2 1 2 3 1 1 2 3 4 5
##### 2 CommentiMostra NessunoNascondi Nessuno
xiyou fu il 17 Set 2016
Good! but when the length of x is large, it seems to be a little slow, is there any more efficient ways ?
Walter Roberson il 18 Set 2016
Yes, you could write a mex file to do the work.
You can calculate the size of the output as sum() of the inputs, and you can pre-allocate that, and you can have a loop to fill it in, but it is not at all clear that it would end up being more efficient than what Teja shows.

Accedi per commentare.

Image Analyst il 17 Set 2016
What rule are you using to generate that output? Here are several ways:
% Define input data.
x=[2 3 1 5]
% Generate a vector [1 2 1 2 3 1 1 2 3 4 5]:
output1 = [x(3), x(1), x(3), x(1), x(2), x(3), 1:length(x), x(end)]
output2 = [x([3, 1, 3, 1, 2, 3]), 1:length(x), x(end)]
output3 = [1 2 1 2 3 1 1 2 3 4 5];
output4 = [x([3, 1, 3, 1, 2, 3]), 1:5]
I'm sure there is a near infinite number of other rules that can get you that output vector. So what is your rule?
##### 2 CommentiMostra NessunoNascondi Nessuno
xiyou fu il 18 Set 2016
I am sorry I didn't make the question clearly. In fact ,I have a for loop in my code, in the loop I can get a vector x (it's length will change with every loop), let's first make x=[2 3 1 5] for example, I want to generate another vector, which has the form like [1 2 1 2 3 1 1 2 3 4 5]. How can I do it in a efficient way? Thank you for your help.
Image Analyst il 18 Set 2016
Tell me the rule. I don't have the Crystal Ball Toolbox yet and since you didn't share your for loop code, I don't know what you tried to do. You still haven't told me the rule even though I explicitly asked.
I gave you 4 ways to build that vector. What's wrong with them?

Accedi per commentare.

Andrei Bobrov il 19 Set 2016
x = x(:);
ons = ones(sum(x),1);
ii = cumsum(x)+1;
ons(ii(1:end-1)) = ons(ii(1:end-1)) - x(1:end-1);
out = cumsum(ons);
##### 2 CommentiMostra NessunoNascondi Nessuno
xiyou fu il 19 Set 2016
The solution is good! Thank you!
David Goodmanson il 19 Set 2016
cool!

Accedi per commentare.

### Categorie

Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by