Fill in array with different lengths of variables at different locations

2 visualizzazioni (ultimi 30 giorni)
What is the most efficient way to fill in an array with a problem as below:
A = [4 6 7 8 9 13 15 20];
I want to fill the array so that a condition is satisfied, in this example that the difference between each array entry is not more than 1.
In a way that the result is:
result = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
Of course, my condition is different but this is the same flow of question. My issue with for loops is that the predefined length of the array is changing.

Risposta accettata

dpb
dpb il 29 Mar 2021
The trick for stuff like this is to "grow" from the back to the front -- so the indices you haven't gotten to yet don't change by the changes you have made:
A=[4 6 7 8 9 13 15 20]; % sample data vector
% the engine
ix=flip(find(diff([A(1) A])>1)); % find locations with diff>1; reverse order
for i=1:numel(ix) % for each "hole" location found
vfill=[A(ix(i)-1)+1:A(ix(i))-1]; % compute the missing values between existing elements
A=[A(1:ix(i)-1) vfill A(ix(i):end)]; % insert in place
end
For your sample case and fill-in rule, the above results in:
>> A
A =
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
>>
NB: The other "trick" not outlined is in the calculation of the ix vector, I augmented A with A(i) so the short-by-one indices returned by find on the diff() result would be in terms of the original length of A, not the shorter length.
Using A(1) ensures there isn't a true value in the first location as a result of diff(); one could just as well augment the resultant output of the logical test or add one to the result and not augment.
Or, of course, use "+1" for all the addressing or treat the location as the end of the complete sequence instead the beginning of the next past the "hole". Many ways to skin the cat... :)

Più risposte (1)

Matt J
Matt J il 29 Mar 2021
Modificato: Matt J il 29 Mar 2021
Of course, my condition is different but this is the same flow of question.
No, the solution will very much depend on the rule for filling the gaps. Here is one way to implement your example loop-free:
A = [4 6 7 8 9 13 15 20];
F=griddedInterpolant(A,A);
result=F(1:max(A))
result = 1×20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  1 Commento
dpb
dpb il 29 Mar 2021
Modificato: dpb il 29 Mar 2021
+1 for the specific rule.
Hopefully the looping construct will facilitate dealing with different infill rules.

Accedi per commentare.

Categorie

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

Prodotti


Release

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by