for looop convert to arrayfun

4 views (last 30 days)
Question Mr
Question Mr on 29 Apr 2021
Edited: Matt J on 30 Apr 2021
I want to convert these for loops into an arrayfun. Always give me an error
"All of the input arguments must be of the same size and shape.
Previous inputs had size 31 in dimension 1. Input #5 has size 1"
[X,Y,Z] = sph2cart(ThetaRad,PhiRad,1.0);
nElec = length(M.lab);
EF(nElec,nElec) = 0;
for i = 1:nElec;
for j = 1:nElec;
EF(i,j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end;
end;
I tried to create a new funciton:
function EF = gpuefg(X,Y,Z, maxiter)
EF(maxiter,maxiter) = 0;
for i = 1:maxiter;
for j = 1:maxiter;
EF(i,j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end;
end;
end
And call it
EFG = gpuArray(EF);
.
.
.
EFG = arrayfun(@gpuefg,X,Y,Z, nElec, 'UniformOutput', false );
But not working, how should I do this?
  2 Comments
Question Mr
Question Mr on 29 Apr 2021
Here is my original code: (not the whole is just the point)
[X,Y,Z] = sph2cart(ThetaRad,PhiRad,1.0);
nElec = length(M.lab);
EF(nElec,nElec) = 0;
for i = 1:nElec;
for j = 1:nElec;
EF(i,j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end;
end;
output is a matrix
And I tried to create my own function for change two "for" loop
function EF = gpuefg(X,Y,Z, maxiter)
EF(maxiter,maxiter) = 0;
for i = 1:maxiter;
for j = 1:maxiter;
EF(i,j) = 1 - ( ( (X(i) - X(j))^2 + ...
(Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
end;
end;
end
Output is matrix like in the original "EF(i,j)" (well that is the plan)
When I called:
EFG = gpuArray(EF);
...
EFG = arrayfun(@gpuefg,X,Y,Z, nElec, 'UniformOutput', false );
It's crashed but I dont know why,
EFG is a gpuArray,
X,Y,Z my function's inputs
nElec is my function's maxiter
So the point is, I want to swap these two "for loops" for one "arryfun"

Sign in to comment.

Accepted Answer

Matt J
Matt J on 29 Apr 2021
Edited: Matt J on 29 Apr 2021
The way to do this with arrayfun, (which I don't think will be optimal here) would be,
[I,J]=ndgrid(gpuArray(1:nElec));
fun=@(i,j) 1 - ( ( (X(i) - X(j))^2 + (Y(i) - Y(j))^2 + (Z(i) - Z(j))^2 ) / 2 );
EF= arrayfun(fun,I,J);
  4 Comments
Matt J
Matt J on 30 Apr 2021
Why did you Accept the answer if it didn't work? Why not just go with the other answer, which I told you should be better than arrayfun?

Sign in to comment.

More Answers (1)

Matt J
Matt J on 29 Apr 2021
Edited: Matt J on 29 Apr 2021
The more efficient way to do what you are attempting is with the 2 lines of code,
X=X(:); Y=Y(:); Z=Z(:);
EF = 1 - ( (X-X.').^2 + (Y-Y.').^2 + (Z-Z.').^2)/2 ;

Community Treasure Hunt

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

Start Hunting!