I am trying to use a parallel loop in Matlab. A simplified code is as follows:
M = 10;
N = 10;
K = 10;
A = zeros(M,N,K);
parfor m = 1:M
for n = 1:N
A(m,n,1) = m;
for k = 2:K
A(m,n,k) = A(m,n,k-1)+randn(1);
end
end
end
It can not run successfully and Matlab tells me "Valid indices for 'A' are restricted in PARFOR loops". Hope someone know how to fix this. Thanks a lot!
Related
I am programing a "customer satisfaction" model which I should use max and min in one linear programing. How can I do that? I have this Idea to use max term as a "subtraction" so it's get minimize in the code line; am I doing right?
I have another question too, how can I formulate a sigma such as picture in matlab whithout getting error?
as you seem we have Qst and Xst but three sigma (s, r and t), I wonder if my model has problem and I don't know how program this.
can you help me please?
I don't quite understand what you are describing in your first question, but you can calculate your MinZ1 using nested loops:
s = randi(5);
r = randi(5);
t = randi(5);
Q = rand([s,r]);
X = rand([s,t]);
L = rand([r,s,t]);
M = rand([r,s,t]);
C = rand([s,r]);
S = rand(1);
P = rand(1);
R = rand(1);
MinZ1 = 0;
for si = 1:s
for ri = 1:r
for ti = 1:t
MinZ1 = MinZ1 + Q(si,ri)*X(si,ti);
end
end
end
for si = 1:s
for ri = 1:r
for ti = 1:t
MinZ1 = MinZ1 + S*L(ri,si,ti)*(P*M(ri,si,ti)+R*C(si,ri));
end
end
end
end
disp(MinZ1)
If you don't like nested loops, you can achieve the same result by generating all indices combinations and passing the result to the sum function.
[si,ri,ti] = ndgrid(1:s,1:r,1:t);
MinZ1 = sum(Q(sub2ind(size(Q),si,ri)).*X(sub2ind(size(X),si,ti)),'all') + sum(S.*L(sub2ind(size(L),ri,si,ti)).*(P.*M(sub2ind(size(M),ri,si,ti))+R.*C(sub2ind(size(C),si,ri))),'all');
I am trying to convert my code over to run with parfor, since as it is it takes a long time to run on its own. However I keep getting this error. I have search around on the website and have read people with similar problems, but none of those answers seem to fix my problem. This is my code:
r = 5;
Mu = 12.57e-9;
Nu = 12e6;
I = 1.8;
const = pi*Nu*Mu*r*I;
a = 55;
b = 69;
c = 206;
[m,n,p] = size(Lesion_Visible);
A = zeros(m,n,p);
parpool(2)
syms k
parfor J = 1:m
for I = 1:n
for K = 1:p
if Lesion_Visible(J,I,K) ~= 0
Theta = atand((J-b)/(I-a));
Rho = abs((I-a)/cosd(Theta))*0.05;
Z = abs(c-K)*0.05;
E = vpa(const*int(abs(besselj(0,Rho*k)*exp(-Z*k)*besselj(0,r*k)),0,20),5);
A (J,I,K) = E;
end
end
end
end
I'm trying to calculate the electric field in specific position on an array and matlab give me the error "The variable A in a parfor cannot be classified". I need help. Thanks.
As classification of variables in parfor loop is not permitted, you should try to save the output of each loop in a variable & then save the final output into the desired variable, A in your case!
This should do the job-
parfor J = 1:m
B=zeros(n,p); %create a padding matrix of two dimension
for I = 1:n
C=zeros(p); %create a padding matrix of one dimension
for K = 1:p
if Lesion_Visible(J,I,K) ~= 0
Theta = atand((J-b)./(I-a));
Rho = abs((I-a)./cosd(Theta))*0.05;
Z = abs(c-K).*0.05;
E = vpa(const.*int(abs(besselj(0,Rho.*k).*exp(-Z.*k).*besselj(0,r.*k)),0,20),5);
C(K) = E; %save output of innnermost loop to the padded matrix C
end
end
B(I,:)=C; % save the output to dim1 I of matrix B
end
A(J,:,:)=B; save the output to dim1 J of final matrix A
end
Go through the following for better understanding-
http://www.mathworks.com/help/distcomp/classification-of-variables-in-parfor-loops.html
http://in.mathworks.com/help/distcomp/sliced-variable.html
How can I optimize these for loop? I learned about optimizing by using matrix instead of loops, but in this case, I don't know what to do.
for j = 2:n
for i = sum(R(1:j-1,1)) : sum(R(1:j,1))
F(1,i) = -s(j,1) * F_0;
end
end
Here is a vectorized form:
I = R(1,1):sum(R(:,1));
J = repelem(2:n,[R(2:end-1,1) ;R(end,1)+1]);
F(1,I) = -s(J,1) * F_0;
explanation:
You can run the loop with an example data and see how i and j will change
n = 7
R = randi([1 5],n,1)
for j = 2:n
for i = sum(R(1:j-1,1)) : sum(R(1:j,1))
disp([i j])
end
end
and based on that you can write a vectorized form.
At first I create a script giving the name multi_002
After I create the function that includes the equation
The script calls the function and reads the array 'a'.
Each array include one equation a(i) = x - i
I want to minimize its equation of the 4 lines array 'a'.
I suspect that something doesn't work right. I notice that
Optimtool works but f1,f2,f3,f4 doesn't go to zero. With another words
there isn't convergence.
FitnessFunction = #array_002;
numberOfVariables = 1;
[x,fval] = gamultiobj(FitnessFunction,numberOfVariables);
function [a,y,c]= array_002(x)
size = 4; n = 4;
y = zeros(size,1);
c = zeros(size,1);
for i = 1:n
y(i) = x;
c(i) = i;
a = y - c;
end
Why my genetic algorithm doesn't converge? Is there any idea?
Thank you in advance!
I am trying to compute the pairwise distances between two struct objects. This distance is symmetric. I have about N = 8000, such objects in an array.
So I need to compute N * (N+1)/2 distances only. How can I parallelize this computation, since each computation is independent ?
Here my objects are stored in Array X and I want to store the distances in Array A which is of size N*(N+1)/2. BDHMM() is a function which returns the distance between two objects.
I have tried the following Matlab Code.
N = 8000;
load inithmm.mat
size = N*(N+1)/2;
A = zeros(size,1);
matlabpool open local 4
parfor i = 1:N-1
i
T = [];
for j = i:N
if(j == i)
temp = 0;
else
temp = BDHMM(X(i),X(j));
end
T = [T; temp];
end
beg = size - (N + 1 - i)*(N + 2 - i)/2 + 1;
l = length(T);
A(beg:beg+l-1, 1) = T;
end
matlabpool close
I am getting the following error:
Error: The variable A in a parfor cannot be classified.
Please help.
You cannot assassin to indexes you calculate withing the parfor, Matlab needs to know in advance what sections of the matrix will be assassin by witch iteration. this makes sense if you think about it.
this should solve it:
N = 800;
size = N*(N+1)/2;
A = cell(N,1);
matlabpool open local 4
parfor i = 1:N-1
i
T = zeros(N-i+1,1);
for j = i:N
if(j == i)
T(j-i+1) = 0;
else
T(j-i+1) = BDHMM(X(i),X(j));
end
end
A{i, 1} = T;
end
matlabpool close
B=vertcat(A{:})