How can I create a matrix with arrayfun
25 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Question Mr
el 1 de Mayo de 2021
Respondida: Question Mr
el 1 de Mayo de 2021
i tried to swap the 2 FOR loops for arrayfun but i don't understand why it never wants to succeed.
TR = (2 * pi * M.theta) / 360;
PR = (2 * pi * M.phi) / 360;
[X,Y,Z] = sph2cart(TR,PR,1.0);
max = length(M.lab);
M(max,max) = 0;
MG = gpuArray(M);
for i = 1:max;
for j = 1:max;
M(i,j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end;
end;
I have tried to implement these two for loops another function like this:
function M = gpuefg(X,Y,Z, maxiter)
M(maxiter,maxiter) = 0;
for i = 1:maxiter;
for j = 1:maxiter;
M(i,j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end;
end;
end
and when I called its not worked. Wrong size.
I dont understand how can I swap these to for loops only for an arrayfun
Or how can I "create" a matrix with use arrayfun and use numerical calculations in the arrayfun?
I tried several ways but nothing
CG = arrayfun(@(X,Y,Z,max) gpuefg(X,Y,Z,max) );
CG = arrayfun(@gpuefg, M);
CG = arrayfun(@(X,Y,Z,max) gpuefg(X,Y,Z,max), M);
CG = arrayfun( @(X,Y,Z,max) gpuefg(M, X,Y,Z,max), X,Y,Z,max, 'UniformOutput', false );
0 comentarios
Respuesta aceptada
Jan
el 1 de Mayo de 2021
The purpose of arrayfun is: "Apply function to each element of array".
This is not what you do in the nested for loops. This is a combination of different elements of different arrays. This means, that arrayfun is not a suitable apporach. Even if you get it to work, arrayfun is not necessarily faster than the clean and neat loops.
2 comentarios
Jan
el 1 de Mayo de 2021
Editada: Jan
el 1 de Mayo de 2021
arrayfun provides the elements of the arrays elementwise to the function. Then the function gets X(i), Y(i), Z(i) only. The loop needs the complete arrays X,Y,Z also, so they have to be provided again as additional inputs. This is such indirect, that I would could assess this as "aggressive code obfuscation". Creating a matrix based on vectors using arrayfun is a really strange approach.
By the way, it makes it easier to write an asnwer if you provide running code. I have to guess, what M.theta, M.phi and M.lab is.
function speedTest
% Guessed test data:
n = 1e4;
TR = (2 * pi * linspace(0, pi, n)) / 360;
PR = (2 * pi * linspace(0, pi, n)) / 360;
[X,Y,Z] = sph2cart(TR,PR,1.0);
m = n;
% Original approach:
M(m,m) = 0;
tic
for i = 1:m
for j = 1:m
M(i, j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end
end
toc
% Much faster with swapped loops (columnwise processing):
M2(m,m) = 0;
tic
for j = 1:m
for i = 1:m
M2(i, j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end
end
toc
% Inner loop vectorized:
M3(m,m) = 0;
tic
for j = 1:m
M3(:, j) = 1 - 0.5 * ((X(:) - X(j)) .^ 2 + ...
(Y(:) - Y(j)) .^ 2 + (Z(:) - Z(j)) .^ 2) ;
end
toc
% Both loops vectorized:
tic;
M4 = 1 - 0.5 * ((X - X(:)) .^ 2 + (Y - Y(:)) .^ 2 + (Z - Z(:)) .^ 2);
toc
% Strange arrayfun approach:
tic
MC5 = arrayfun(@(x,y,z) fun(x,y,z, X,Y,Z, m), X, Y, Z, 'UniformOutput', false);
M5 = cat(1, MC5{:});
toc
% Do we get the same results?
isequal(M, M2, M3, M4, M5)
end
function M = fun(xi,yi,zi, X,Y,Z, m)
M(1, m) = 0;
for j = 1:m
M(j) = 1 - 0.5 * ((xi - X(j))^2 + (yi - Y(j))^2 + (zi - Z(j))^2);
end
end
% Core i7, Matlab R2018b:
% Elapsed time is 4.009399 seconds. Original
% Elapsed time is 0.390634 seconds. Swapped loops (10 times faster!)
% Elapsed time is 0.133837 seconds. Inner loop vectorized
% Elapsed time is 0.249436 seconds. Both loops vectorized
% Elapsed time is 2.565760 seconds. Strange arrayfun approach
Más respuestas (1)
Ver también
Categorías
Más información sobre GPU Computing in MATLAB en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!