Adding elements to the ends of vectors inside a cell array of vectors
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
Is there a way to add elements to the ends of vectors that are inside a cell array of vectors which would be faster than the following code that uses a for-loop?
x = rand(1,20);
i1 = [1,7,11];
i2 = [6,10,20];
xLower = [0.1 0.2 0.3];
xUpper = [100 200 300];
tic();
for r = 1:length(i1)
xRegion{r} = [xLower(r) x(i1(r):i2(r)) xUpper(r)];
end
toc();
xRegion
Accepted Answer
Eike Blechschmidt
on 29 Jul 2021
You could use arrayfun:
arrayfun(@(l,i1,i2,u) [l x(i1:i2) u], xLower,i1,i2, xUpper, “uniform“, false)
This is untested but should be faster.
8 Comments
Mark Szlazak
on 30 Jul 2021
Edited: Mark Szlazak
on 30 Jul 2021
Thanks for the attempt but on this example your code was almost 5x slower. For more typical problems I use this code on then your version is about 2x slower. Maybe when the sizes get large enough there is a speed gain but that might not be something I would encounter.
Eike Blechschmidt
on 30 Jul 2021
Edited: Eike Blechschmidt
on 30 Jul 2021
You are right. Arrayfun only speeds up the if the data is significantly larger. For speed improvements it is essential to know the problem best. Can you be a bit more specific on the size of the data?
Additionally in more recent versions for loops are optimized by matlab quite well when it comes to speed.
Mark Szlazak
on 30 Jul 2021
I will have better estimates on "size-of-data" after some more testing and integration. At least I have your alternative to try when that happens. Thx
"Arrayfun only speeds up the if the data is significantly larger."
In general ARRAYFUN and CELLFUN are slower than the equivalent (well-written) loops.
"This is untested but should be faster."
Very unlikely. Experienced MATLAB users would expect it to be slower than a well-written loop:
etc.etc.
Eike Blechschmidt
on 30 Jul 2021
Thank you Stephen for pointing out that arrayfun and cellfun are slower than for loops nowadays. My experience of matlab might be a bit rusty from times where it was necessary to avoid for loops to get performance. I guess I’m not the only one: Blogpost by Mike Croucher. When it comes to performance I think it is essential to write benchmarks and test using real or comparable data to test performance of different implementations. That would probably have prevented me from writing the above (untested) answer.
Mark Szlazak
on 1 Aug 2021
Edited: Mark Szlazak
on 1 Aug 2021
Thank you everyone for the input on for-loop speed and arrayfun. I was wondering if pre-allocation of the cell array would help. However, if that is the case then I am not sure how to set that cell-array pre-allocation up.
cell(length(i1), 1, i2 - i1 + 2)
doesn't work since the first value of i2 - i1 + 2 is used throughout.
maxSz = max(i2 - i1 + 2)
cell(length(i1), 1, maxSz)
sets all vectors to the same maximum size but not to the various sizes of i2 - i1 + 2 of the vectors in each row of the cell array.
Eike Blechschmidt
on 1 Aug 2021
Edited: Eike Blechschmidt
on 1 Aug 2021
You have to differentiate between allocating the cell array and allocating for the actual content of the cell array. Basically your cell array is just storing a bunch of pointers to the actual arrays of double you create in your for loop.
So it would only make sense to do the following which in your current example does not bring any benefit as i1 is quite small (I tried that on my machine):
xRegion = cell(size(i1))
I don't know a way to pre allocate memory for the created double arrays from your loop which would not involve a loop.
Depending on how you later processes the data it could could be worth trying just to use a pre-allocated doble array instead and set all not needed fields to nan. Again just gussing if that even does speed up your code.
arrSize = i2 - i1 + 3;
xRegion1 = nan(length(i1), max(i2 - i1 + 2));
for r = 1:length(i1)
xRegion1(r, 1:arrSize(r)) = [xLower(r) x(i1(r):i2(r)) xUpper(r)];
end
Mark Szlazak
on 2 Aug 2021
Thanks for the explanation on this type of pre-allocation.
More Answers (0)
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Products
See Also
on 29 Jul 2021
on 2 Aug 2021
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)