Optimization using Cell Arrays

Hello,
I'v been trying to optimize the existing code below. This calculation is done one at a time for 336000 of c1, r1, and slope.
Rinter = zeros(1080,1);
for r = 1:1080
Rinter(r) = c1 + (r-r1) / slope;
end
I redid the variables c1,r1,slope to be calculated all at once using cellfun. So now I have r1,c1,slope = 336 cell arrays with each cell holds 1000 values. I'm trying to figure out how to optimize the code so that:
Rinter = zeros(1080,1);
for r = 1:1080
Rinter(r) = c1{1:336,1}(1:1000) + (r-r1{1:336,1}(1:1000)) / slope{1:336}(1:1000);
end
any help is appreciated since I'm rather confused now. Thanks!

5 commentaires

Torsten
Torsten le 12 Juil 2023
Modifié(e) : Torsten le 12 Juil 2023
I wonder what you expect as result for Rinter from the operation
Rinter(r) = c1{1:336,1}(1:1000) + (r-r1{1:336,1}(1:1000)) / slope{1:336}(1:1000);
I suspect that you want to save 336000 values for each value of r(i) (i = 1,...,1080), but how should this be possible in one scalar value Rinter(r) ?
James Tursa
James Tursa le 12 Juil 2023
You need to tell us exactly what r1, c1, and slope are (variable size and type etc.). A small example of inputs and desired output would also help.
DB
DB le 12 Juil 2023
yes, I want to save all the 336000 values for each of r(1:1080) which I will then use later for more calculations. I suppose I can define Rinter as cell array? r1,c1,slope are all type double -> 336X1 cell array and each cell contains (1000 x1 double). Here are the first 3 values out of the 1000 in cell 1:
r1{1,1} =
538.066700563257
539.176467549361
537.641860711957
c1{1,1} =
145.906518570733
146.998492549802
145.488490220006
slope(1,1} =
-0.980866192253173
-0.989057988958667
-0.982385707846712
Here's the expected Rinter(1:3) just from 1 value of c1,r1,slope out of 1080:
693.449807150745
692.430300098817
691.410793046889
maybe there's a better way(faster way) to do the calculation and storing them? Thanks.
Torsten
Torsten le 12 Juil 2023
Modifié(e) : Torsten le 12 Juil 2023
I don't understand your example. Since r is a scalar in your equation
Rinter(r) = c1{1:336,1}(1:1000) + (r-r1{1:336,1}(1:1000)) / slope{1:336}(1:1000);
shouldn't the components of the vector R = r*[1; 1; 1] be the same ?
r1{1,1} = ...
[538.066700563257
539.176467549361
537.641860711957];
c1{1,1} = ...
[145.906518570733
146.998492549802
145.488490220006];
slope{1,1} = ...
[-0.980866192253173
-0.989057988958667
-0.982385707846712];
Rinter{1,1} = ...
[693.449807150745
692.430300098817
691.410793046889];
R = (Rinter{1,1}-c1{1,1}).*slope{1,1}+r1{1,1}
R = 3×1
1.0000 -0.2872 1.3356
DB
DB le 13 Juil 2023
@Torsten, for every R(i) -> i=1:1080, I'm calculating:
for r = 1:1080
Rinter(r) = c1 + (r-r1) / slope;
end
However, my c1, r1, and slope are now cell arrays of 336 cells with 1000 in each of the cell.
Above calculation of R(1:3) using c1,r1,slope {1,1}(1) are correct:
Rinter(1) = 145.906518570733 + (1 - 538.066700563257)/-0.980866192253173; --> 693.4498
Rinter(2) = 145.906518570733 + (2 - 538.066700563257)/-0.980866192253173; --> 692.4303
Rinter(3) = 145.906518570733 + (3 - 538.066700563257)/-0.980866192253173; --> 691.4108

Connectez-vous pour commenter.

Réponses (1)

Image Analyst
Image Analyst le 12 Juil 2023

0 votes

Just use a normal double array. Cell arrays are slow and very inefficient and are a special type of variable for situations where every element (cell) might have a different type or different number of elements in each cell. See the FAQ:
Since that does not apply in your situation, a normal double array would be the best, fastest, and most efficient approach.

3 commentaires

Rik
Rik le 13 Juil 2023
Adding to this: you seem under the impression that using cellfun will be faster than a loop. It will not. Only the legacy syntax (i.e. cellfun('prodofsize',___); etc.) are faster than a loop with a function call. cellfun and its friend only hide the loop, adding a bit of overhead while doing so.
DB
DB le 13 Juil 2023
it is faster to calculate a lot of variables at once using arrayfun and cellfun instead of foor loop. For example:
tic
[r2A,c2A] = arrayfun(@(x,y) RPD(x,y,angle),r2,c2,'un', 0);
toc
tic
Elapsed time is 0.001386 seconds.
for i = 1:336
[r2l(i),c2l(i)] = RPD(r2(i),c2(i),angle);
end
toc
Elapsed time is 0.012329 seconds.
@Image Analyst However, the results of using arrayfun will be cell arrays instead of normal double array. Will converting them before and after calculations be efficient? I'm trying to simplify the code (performance speed and less lines of code).
You should use timeit when dealing with code that takes less than a second. You should also properly preallocate the output arrays.
r2l = zeros(1,336);
c2l = zeros(1,336);
for i = 1:336
[r2l(i),c2l(i)] = RPD(r2(i),c2(i),angle);
end

Connectez-vous pour commenter.

Catégories

En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange

Produits

Version

R2023a

Tags

Question posée :

DB
le 12 Juil 2023

Commenté :

Rik
le 13 Juil 2023

Community Treasure Hunt

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

Start Hunting!

Translated by