Related
I have a script that I'm running, and at one point I have a loop over n objects, where I want n to be fairly large.
I have access to a server, so I put in a parfor loop. However, this is incredibly slow compared with a standard for loops.
For example, running a certain configuration ( the one below ) with the parfor loop on 35 workers took 68 seconds, whereas the for loop took 2.3 seconds.
I know there's stuff to do with array-broadcasting that can cause issues, but I don't know a lot about this.
n = 20;
r = 1/30;
tic
X = rand([2,n-1]);
X = [X,[0.5;0.5]];
D = sq_distance(X,X);
A = sparse((D < r) - eye(n));
% Infected set I
I = n;
[S,C] = graphconncomp(A);
compnum = C(I);
I_new = find(C == compnum);
I = I_new;
figure%('visible','off')
gplot(A,X')
hold on
plot(X(1,I),X(2,I),'r.')
hold off
title('time = 0')
axis([0,1,0,1])
time = 0;
t_max = 10; t_int = 1/100;
TIME = 1; T_plot = t_int^(-1) /100;
loops = t_max / T_plot;
F(loops) = struct('cdata',[],'colormap',[]);
F(1) = getframe;
% Probability of healing in interval of length t_int
heal_rate = 1/3; % (higher number is faster heal)
p_heal = t_int * heal_rate;
numhealed = 0;
while time < t_max
time = time+t_int;
steps = poissrnd(t_int,[n,1]);
parfor k = 1:n
for s = 1:steps(k)
unit_vec = unif_unitvector;
X_new = X(:,k) + unit_vec*t_int;
if ( X_new < 1 == ones(2,1) ) ...
& ( X_new > 0 == ones(2,1) )
X(:,k) = X_new;
end
end
end
D = sq_distance(X,X);
A = sparse((D < r) - eye(n));
[S,C] = graphconncomp(A);
particles_healed = binornd(ones(length(I),1),p_heal);
still_infected = find(particles_healed == 0);
I = I(still_infected);
numhealed = numhealed + sum(particles_healed);
I_new = I;
% compnum = zeros(length(I),1);
for i = 1:length(I)
compnum = C(I(i));
I_new = union(I_new,find(C == compnum));
end
I = I_new;
if time >= T_plot*TIME
gplot(A,X')
hold on
plot(X(1,I),X(2,I),'r.')
hold off
title(sprintf('time = %1g',time))
axis([0,1,0,1])
% fprintf('number healed = %1g\n',numhealed)
numhealed = 0;
F(TIME) = getframe;
TIME = TIME + 1;
end
end
toc
This is my matlab code. It runs too slow and I had no clue how to improve it.
Could you help me to improve the speed?
What I would like to do is to create some random points and then remove the random points to make them similar to my target points.
syms Dx Dy p q;
a = 0;
num = 10;
x = rand(1,num);
y = rand(1,num);
figure(1)
scatter(x,y,'.','g')
%num_x = xlsread('F:\bin\test_2');% num 1024
%figure(2)
%scatter(num_x(:,1),num_x(:,2),'.','r');
q = 0;
num_q = 10;
x_q = randn(1,num_q);
y_q = randn(1,num_q);
%figure(2)
hold on;
scatter(x_q,y_q,'.','r')
for i = 1:num_q;
for j = 1:num_q;
qx(i,j) = x_q(i) - x_q(j);
qy(i,j) = y_q(i) - y_q(j);
%qx(i,j) = num_x(i,1) - num_x(j,1);
%qy(i,j) = num_x(i,2) - num_x(j,2);
%d~(s(i),s(j))
if ((qx(i,j))^2+(qy(i,j)^2))> 0.01 % find neighbours
qx(i,j) = 0;
qy(i,j) = 0;
end
end
end
for i = 1:num_q;
for j = 1:num_q;
if qx(i,j)>0&&qy(i,j)>0
q = q + exp(-(((Dx - qx(i,j))^2)+((Dy - qy(i,j))^2))/4);%exp(-(((Dx - qx(i,j))^2)+((Dy - qy(i,j))^2))/4);
end
end
end
%I = ones(num,num); % I(s) should from a grayscale image
%r = 1./sqrt(I);
for s = 1:100;
for i = 1:num;
for j = 1:num;
dx(i,j) = x(i) - x(j);
dy(i,j) = y(i) - y(j);
%d~(s(i),s(j))
if ((dx(i,j))^2+(dy(i,j)^2))> 0.05 % delta p, find neighbours
dx(i,j) = 0;
dy(i,j) = 0;
end
end
end
p = 0;
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0
p = p + exp(-(((Dx - dx(i,j))^2)+((Dy - dy(i,j))^2))/4);
end
end
end
p = p - q;
sum = 0;
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0;
kx(i,j) = (1/2)*(Dx-dx(i,j))*exp((-(Dx-dx(i,j))^2+(Dy-dy(i,j))^2)/4);
ky(i,j) = (1/2)*(Dy-dy(i,j))*exp((-(Dx-dx(i,j))^2+(Dy-dy(i,j))^2)/4);
end
end
end
sum_x = ones(1,num);% 1行N列0矩阵
sum_y = ones(1,num);
%fx = zeros(1,num);
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0;
fx(i) = p*kx(i,j);% j is neighbour to i
fy(i) = p*ky(i,j);
%fx(i) = matlabFunction(fx(i));
%fy(i) = matlabFunction(fy(i));
%P =quad2d(#(Dx,Dy) fx,0,0.01,0,0.01);
%fx =quad(#(Dx) fx,0,0.01);
%fx(i) =quad(#(Dy) fx(i),0,0.01);
%Q =quad2d(#(Dx,Dy) fy,0,0.01,0,0.01);
fx(i) = double(int(int(fx(i),Dx,0,0.01),Dy,0,0.01));
fy(i) = double(int(int(fy(i),Dx,0,0.01),Dy,0,0.01));
%fx(i) = vpa(p*kx(i,j));
%fy(i) = vpa(p*ky(i,j));
%fx(i) = dblquad(#(Dx,Dy)fx(i),0,0.01,0,0.01);
%fy(i) = dblquad(#(Dx,Dy)fy(i),0,0.01,0,0.01);
sum_x(i) = sum_x(i) + fx(i);
sum_y(i) = sum_y(i) + fy(i);
end
end
end
for i = 1:num;
sum_x = 4.*sum_x./num;
sum_y = 4.*sum_y./num;
x(i) = x(i) - 0.05*sum_x(i);
y(i) = y(i) - 0.05*sum_y(i);
end
a = a+1
end
hold on;
scatter(x,y,'.','b')
The fast version of your loop should be something like:
qx = bsxfun(#minus, x_q.', x_q);
qy = bsxfun(#minus, y_q.', y_q);
il = (qx.^2 + qy.^2 >= 0.01);
qx(il) = 0;
qy(il) = 0;
il = qx>0 && qy>0;
q = sum(exp(-((Dx-qx(il)).^2 + (Dy-qy(il)).^2)/4));
%// etc. for vectorization of the inner loops
I currently have an error that i can't pass this is the short code and everything needed in order to have a general idea about my problem
clear;
close all; clear ;
load fisheriris;
m = meas;
d = num2cell(m);
d(:,5) = species(:,1);
c = cvpartition(d(:,5),'kfold',10);
CeDam = cell(10,1);
CeVrem = cell(10,1);
for i=1:10
CeDam{i} = [d(test(c,i),1) d(test(c,i),2) d(test(c,i),3) d(test(c,i),4)]';
end
for i=1:10
CeVrem{i} = d(test(c,i),5)';
end
for i = 1:10
a = CeVrem{i};
[n,m] = size(a);
for j = 1:n
for k = 1:m
if isequal(a(j,k),'setosa') a{n,m} = [1 0 0];
elseif isequal(a(j,k),'versicolor') a{n,m} = [0 1 0];
else a{j,k} = [0,0,1];
end
end
end
CeVrem{i} = a;
end
net = newff(cell2mat(minmax(CeDam{1})),[3 3 3],{'logsig','logsig','logsig',},'trainlm');
net.LW{2,1} = net.LW{2,1}*0.5;
net.b{2} = net.b{2}*2;
net.performFcn = 'mse';
net.trainParam.epochs = 100;
err = 0;
i = 1;
j = 1;
while i <= 10
while j <= 10
if i~=j net = train(net,CeDam{j},CeVrem{j});
end
j=j+1;
end
end
in the train part of the algorithm it gives me an input mistmatch which is very odd for me.
The error messages:
Error using trainlm (line 109) Number of inputs does not match
net.numInputs.
Error in network/train (line 106) [net,tr] =
feval(net.trainFcn,net,X,T,Xi,Ai,EW,net.trainParam);
i managed to fix everything after much work here is the code that works for anyone having the same problem in the future gl :D :).
clear;
close all; clear ;
load fisheriris;
m = meas;
d = num2cell(m);
d(:,5) = species(:,1);
c = cvpartition(d(:,5),'kfold',10);
CeDam = cell(10,1);
CeVrem = cell(10,1);
for i=1:10
CeDam{i} = [m(test(c,i),1) m(test(c,i),2) m(test(c,i),3) m(test(c,i),4)]';
end
for i=1:10
CeVrem{i} = d(test(c,i),5);
end
for i = 1:10
a = CeVrem{i}';
[n,m] = size(a);
b = zeros(3,m);
for j = 1:n
for k = 1:m
if isequal(a(j,k),{'setosa'}) b(1,k) = 1; b(2,k) = 0; b(3,k) = 0;
elseif isequal(a(j,k),{'versicolor'}) b(1,k) = 0; b(2,k) = 1; b(3,k) = 0;
else b(1,k) = 0; b(2,k) = 0; b(3,k) = 1;
end
end
end
CC{i} = b;
end
CC = CC';
net = newff(minmax(CeDam{1}),[3 3 3],{'logsig','logsig','logsig'},'trainlm');
net.LW{2,1} = net.LW{2,1}*0.6;
net.b{2} = net.b{2}*2;
net.performFcn = 'mse';
net.trainParam.epochs = 100;
errglob = 0;
i = 1;
j = 1;
while i <= 10
while j <= 10
if i~=j net = train(net,CeDam{j},CC{j});
end
j=j+1;
end
y=sim(net,CeDam{i});
y=round(y);
e = y - CC{i};
errcur=mse(net,CC{i},y);
errglob = errglob + mse(net,CC{i},y);
fprintf('Avem o eroare de %.2f pe foldul %d \n',errcur,i)
i=i+1;
end
errglob/10
this thread can be closed thx :)
I think you got some problems with mixing up cell and array formats...
Try to replace:
net = train(net,CeDam{j},CeVrem{j});
by:
net = train(net,cell2mat(CeDam{j}),cell2mat(CeVrem{j}')');
AND: please remove your infinite loops in i, by adding i=i+1; or replace the while loops by more natural for loops, e.g.
for i = 1:10
for j = 1:10
if i~=j
net = train(net,cell2mat(CeDam{j}),cell2mat(CeVrem{j}')');
end
end
end
AND: Where are you using your i inside the loop? I guess something is missing there...
I am Trying to convert a MATLAB code to C++ using MATLAB coder but this error apears:
Error indenting generated C code
The error points to the name of the function itself and has no more explanations in it. can someone tell me what is this error?
here is the function i want to conver:
function [Report_Clustered,ClusterCounter_new]=InitClusterGenerator_test(Report_In,~,FreqEpsilon,DegreeEpsilon,~,ClusterCounter_old, BlockCount, Report_old)
Report_M = zeros(size(Report_In,1),size(Report_In,2),4);
for i=1:size(Report_In,1)
for j=1:size(Report_In,2)
Report_M(i,j,1)=Report_In(i,j,1);
Report_M(i,j,2)=Report_In(i,j,2);
Report_M(i,j,3)=0; % Cluster number that the point belongs to.
Report_M(i,j,4)=0;
Report_In{i,j}
end
end
ClusterCounter = 0;
for i=1:size(Report_M,1)
for j=1:size(Report_M,2)
if (Report_M(i,j,3) == 0)
ClusterCounter = ClusterCounter + 1;
Report_M(i,j,3) = ClusterCounter;
for ii=1:size(Report_M,1)
for jj=1:size(Report_M,2)
if (Report_M(ii,jj,3) == 0)
if (abs(Report_M(i,j,1)-Report_M(ii,jj,1))<FreqEpsilon &&...
(abs(Report_M(i,j,2)-Report_M(ii,jj,2)) <DegreeEpsilon ||...
abs(-360 + Report_M(i,j,2)-Report_M(ii,jj,2)) <DegreeEpsilon ||...
abs(360 + Report_M(i,j,2)-Report_M(ii,jj,2)) <DegreeEpsilon))
Report_M(ii,jj,3) = ClusterCounter;
end
end
end
end
end
end
end
if (BlockCount> 20 && ClusterCounter<4)
warning = 1;
end
ClusterCounter_new = ClusterCounter;
%clear Report_new;
flag = 0;
Report_new = zeros(ClusterCounter,size (Report_M, 2),4);
index = zeros(1, ClusterCounter_new);
for i = 1: size (Report_M, 1)
for j = 1: size (Report_M, 2)
for k = 1: ClusterCounter_new
if (Report_M(i,j,3) == k)
index(1,k) = index(1,k) + 1;
Report_new(k,index(1,k), 1:3) = Report_M(i,j,1:3);
flag = flag + 1;
end
end
end
end
for j = 1: size (Report_new, 2)
for i = 1: size (Report_new, 1)
if (Report_new(i,j,1) == 0)
Report_new(i,j,1:3) = Report_new(i,1,1:3);
end
end
end
%Report_new = Report;
MedoidF_old = zeros(1, size(Report_old,1));
MedoidA_old = zeros(1, size(Report_old,1));
for i=1:size(Report_old,1)
SumF = 0;
SumA = 0;
MinAngle = 361;
MaxAngle = -1;
for j=1:size(Report_old,2)
SumF = SumF + Report_old(i,j,1);
SumA = SumA + Report_old(i,j,2);
if Report_old(i,j,2) > MaxAngle
MaxAngle = Report_old(i,j,2);
elseif Report_old(i,j,2) < MinAngle
MinAngle = Report_old(i,j,2);
end
end
MedoidF_old(1, i) = SumF/size(Report_old,2);
if (MaxAngle - MinAngle) > 350
MedoidA_old(1, i) = 0;
else
MedoidA_old(1, i) = SumA/size(Report_old,2);
end
end
MedoidF_new = zeros(1, size(Report_new,1));
MedoidA_new = zeros(1, size(Report_new,1));
for i=1:size(Report_new,1)
SumF = 0;
SumA = 0;
MinAngle = 361;
MaxAngle = -1;
for j=1:size(Report_new,2)
SumF = SumF + Report_new(i,j,1);
SumA = SumA + Report_new(i,j,2);
if Report_new(i,j,2) > MaxAngle
MaxAngle = Report_new(i,j,2);
elseif Report_new(i,j,2) < MinAngle
MinAngle = Report_new(i,j,2);
end
end
MedoidF_new(1, i) = SumF/size(Report_new,2);
if (MaxAngle - MinAngle) > 350
MedoidA_new(1, i) = 0;
else
MedoidA_new(1, i) = SumA/size(Report_new,2);
end
end
TempCluster = zeros(1, size(Report_new, 1));
CurrentCluster = ClusterCounter_old;
for i = 1: 1: size(Report_new,1)
for j = 1: 1: size(Report_old,1)
if (abs(MedoidF_old(1,j)-MedoidF_new(1,i))<FreqEpsilon &&...
(abs(MedoidA_old(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(360 + MedoidA_old(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(-360 + MedoidA_old(1,j)-MedoidA_new(1,i))<DegreeEpsilon)) %%if the new cluster is the rest of an old cluster use the old one's index for it
TempCluster(1,i) = Report_old(j,1,3);
end
end
%%this part is for seperating the clusters which where in the collision state in the past time
if (TempCluster(1,i)>0) %%if the new cluster is one of the old ones the index should be set
for j = 1:1:size(Report_new, 2)
Report_new(i,j,3) = TempCluster(1,i);
Report_new(i,j,4) = 1;% Alive
end
else %%first search if the new cluster is a part of a newly found cluster found before this one
for j = 1: 1: i-1
if (abs(MedoidF_new(1,j)-MedoidF_new(1,i))<FreqEpsilon &&...
(abs(MedoidA_new(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(360 + MedoidA_new(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(-360 + MedoidA_new(1,j)-MedoidA_new(1,i))<DegreeEpsilon)) %%if the new cluster is the rest of an old cluster use the old one's index for it
TempCluster(1,i) = Report_new(j,1,3);
end
end
end
if (TempCluster(1,i)>0) %%if the new cluster is one of the old ones the index should be set
for j = 1:1:size(Report_new, 2)
Report_new(i,j,3) = TempCluster(1,i);
Report_new(i,j,4) = 1;% Alive
end
else %%new cluster is just began so it needs a new index
CurrentCluster = CurrentCluster + 1;
ClusterCounter_new = CurrentCluster;
TempCluster(1,i) = CurrentCluster;
for j = 1:1:size(Report_new, 2)
Report_new(i,j,3) = TempCluster(1,i);
Report_new(i,j,4) = 1; % Alive
end
end
end
NewClusters = zeros(1, size (Report_new, 1));
for i = 1: size(Report_new, 1)
NewClusters (1,i) = Report_new(i,1,3);
end
OldClusters = zeros(1, size (Report_old, 1));
OldClustersLine = zeros(1, size (Report_old, 1));
for i = 1: size(Report_old, 1)
OldClusters (1,i) = Report_old(i,1,3);
OldClustersLine (1, i) = i;
end
NumberOfDead = 0;
%clear AddDead;
AddDead = zeros (16,size(Report_new, 2),4);
if (BlockCount>10)
for i = 1: size (OldClusters, 2)
IsDead = 1;
for j = 1: size (NewClusters, 2)
if OldClusters(1, i) == NewClusters(1,j)
IsDead = 0;
end
end
if (IsDead == 1)
NumberOfDead = NumberOfDead + 1;
%clear TempLine;
TempLine = zeros(1, size(Report_old,2), 4);
TempLine(1,:,1:3) = Report_old(OldClustersLine(1, i),:,1:3);
for k= 1: size(TempLine, 2)
TempLine(1,k,4) = 0; % Dead
end
TempSize = size(TempLine, 2);
Thresh = size(Report_new, 2);
if (TempSize >= Thresh)
AddDead (NumberOfDead, 1:Thresh, 1:4) = TempLine(1,1:Thresh, 1:4);
else
for l = 1: Thresh-TempSize
TempLine(1, TempSize+l, 1:4) = TempLine(1, TempSize, 1:4);
end
AddDead (NumberOfDead, 1:Thresh, 1:4) = TempLine(1,1:Thresh, 1:4);
end
end
end
xR = size (Report_new,1);
if (NumberOfDead == 0)
Report_Clustered = zeros (size(Report_new,1),size(Report_new,2),size(Report_new,3));
else
Report_Clustered = zeros (size(Report_new,1) + NumberOfDead,size(Report_new,2),size(Report_new,3));
end
Report_Clustered (1:size(Report_new,1), :, :) = Report_new(:,:,:);
for i = 1: NumberOfDead
Report_Clustered(xR + i, :) = AddDead(i, :);
end
end
and I'm using matlab 2012a
Tnx.
From what you've said in the comments, it appears that you simply need to call
clear functions
from the command line before recompiling the function to allow Matlab to overwrite the files. See this Matlab forum or the documentation for clear for more detail.
How do we vectorize this sort of code in matlab?
for i = 1:N
for k = 1:64
if (pixels(i,k)==1)
p(character(i),k)= p(character(i),k)+1;
end
end
end
The following should be equivalent:
[i,j] = find(pixels(i,k) == 1);
if ~isempty(i)
ind = sub2ind(size(p), character(i), j);
% or, equivalently:
% ind = character(i) + (j-1) * size(p,1);
p(ind) = p(ind) + 1;
end