Fill in array with different lengths of variables at different locations
2 views (last 30 days)
Show older comments
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.
0 Comments
Accepted Answer
dpb
on 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... :)
0 Comments
More Answers (1)
Matt J
on 29 Mar 2021
Edited: Matt J
on 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))
1 Comment
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!