Info

La pregunta está cerrada. Vuélvala a abrir para editarla o responderla.

Simple Question about Optimization of Nested IF-FOR loops

3 visualizaciones (últimos 30 días)
Mohsen
Mohsen el 17 de Jun. de 2013
Cerrada: MATLAB Answer Bot el 20 de Ag. de 2021
Does any one know how to optimize this code so that it runs faster:
for i=1:iNZ;
if iPointsinSlice>0;
for m=1:iNX;
for l=1:iNY;
if SliceMaskUr(m,l)==1;
DoseCubeU(m+(l-1)*iNX+i*iNX*iNY)=100*SumDose(m,l,i)/RX_Dose;
end
end
end
end
end
Your help is much appreciated! Thanks a lot!

Respuestas (5)

Roger Stafford
Roger Stafford el 17 de Jun. de 2013
Is 'iPointsinSlice' a scalar? If so and if it is not positive, nothing will happen here.
Next, don't you mean "m+(l-1)*iNX+(i-1)*iNX*iNY" as the index to 'DoseCubeU'? As it stands it will vary from 1+iNX*iNY to iNX*iNY*iNZ+iNX*iNY. Assuming my guess is correct, do this:
if iPointsinSlice > 0
t = repmat(SliceMaskUr==1,1,1,iNZ);
DoseCubeU(t) = (100/RX_Dose)*SumDose(t);
end
In case 'iPointsinSlice' is not a scalar you will have to correct your code before we can see how to handle it.
  1 comentario
Mohsen
Mohsen el 17 de Jun. de 2013
'iPointsinSlice' is a scalar. "m+(l-1)*iNX+(i-1)*iNX*iNY" is used as the index to 'DoseCubeU. But your code gives the error that REPMAT has too many arguments. How should I fix it?

Roger Stafford
Roger Stafford el 17 de Jun. de 2013
Sorry! It should have been:
t = repmat(SliceMaskUr==1,[1,1,iNZ]);
  1 comentario
Mohsen
Mohsen el 18 de Jun. de 2013
I changed
DoseCubeU(m+(l-1)*iNX+i*iNY*iNX)=100*SumDose(m,l,i)/RX_Dose;
to
DoseCubeU(double(m)+double((l-1))*double(iNX)+double((i-1))*double(iNY)*double(iNX))=100*SumDose(m,l,i)/RX_Dose;
Otherwise the indexing will not be correct. For example, iNX*iNY*iNZ (which is 120*120*11) becomes equal to 65535 (which is wrong). We should write it as double(iNX)*double(iNY)*double(iNZ) in order to get the correct results (ie. 158400).
By making this change, both the indexing (the initial) method and the subscription method (below) give the same results. But these results are different than any of the other proposed methods.
So, how can I optimize:
for i=1:iNZ;
if iPointsinSlice>0;
for m=1:iNX;
for l=1:iNY;
if SliceMaskUr(m,l)==1;
DoseCubeU(m,l,i)=100*SumDose(m,l,i)/RX_Dose;
end
end
end
end
end

Mohsen
Mohsen el 17 de Jun. de 2013
This code doesn't give me the same result as my initial code. Please note that the purpose of "m+(l-1)*iNX+i*iNX*iNY" is to reshape the SumDose array which is (iNX by iNY by iNZ) to a one dimensional array (1 by iNX*iNY*iNZ).
I tried also
if SliceMaskUr==1;
DoseCubeU= reshape(SumDose,1,[iNX iNY iNZ])*(100/RX_Dose);
end
but it didn't work neither...
Any insight?
  4 comentarios
Mohsen
Mohsen el 18 de Jun. de 2013
I think that the function poly2mask is in charge of these discrepancies. Any idea why? Here is the entire code:
iNNX=double(iNX);
iNNY=double(iNY);
for i=1:iNZ;
iPointsinSlice=1;
for j=1:iNCUr;
if UrContourZ(j)==ZSlice(i);
iPointsinSlice = iPointsinSlice+1;
UrPointX(iPointsinSlice-1)=1 + (UrContourX(j)-Offset(1,1));
UrPointY(iPointsinSlice-1)=1 + (UrContourY(j)-Offset(2,1));
end
end
if iPointsinSlice>0;
indx=round(iPointsinSlice);
indy=round(iPointsinSlice);
indx(1:iPointsinSlice-1)=UrPointX(1:iPointsinSlice-1)/DresX;
indy(1:iPointsinSlice-1)=UrPointY(1:iPointsinSlice-1)/DresY;
SliceMaskUr = poly2mask(indx,indy,iNNX,iNNY);
for m=1:iNX;
for l=1:iNY;
if SliceMaskUr(m,l)==1;
DoseCubeU(m+(l-1)*iNX+(i-1)*iNY*iNX)=100*SumDose(m,l,i)/RX_Dose;
end
end
end
end
end
Your help is much appreciated! :)
Mohsen
Mohsen el 18 de Jun. de 2013
I changed
DoseCubeU(m+(l-1)*iNX+i*iNY*iNX)=100*SumDose(m,l,i)/RX_Dose;
to
DoseCubeU(double(m)+double((l-1))*double(iNX)+double((i-1))*double(iNY)*double(iNX))=100*SumDose(m,l,i)/RX_Dose;
Otherwise the indexing will not be correct. For example, iNX*iNY*iNZ (which is 120*120*11) becomes equal to 65535 (which is wrong). We should write it as double(iNX)*double(iNY)*double(iNZ) in order to get the correct results (ie. 158400).
By making this change, both the indexing (the initial) method and the subscription method (below) give the same results. But these results are different than any of the other proposed methods.
So, how can I optimize:
for i=1:iNZ;
if iPointsinSlice>0;
for m=1:iNX;
for l=1:iNY;
if SliceMaskUr(m,l)==1;
DoseCubeU(m,l,i)=100*SumDose(m,l,i)/RX_Dose;
end
end
end
end
end

Andrei Bobrov
Andrei Bobrov el 18 de Jun. de 2013
Editada: Andrei Bobrov el 19 de Jun. de 2013
DoseCubeU = bsxfun(@times,100*SumDose/RX,SliceMaskUr==1);
ADD
s = SliceMaskUr(end:-1:1,end:-1:1);
tt = cumsum(cumsum(s),2);
t1 = flipud(any(tt,2));
t2 = fliplr(any(tt));
DoseCubeU = bsxfun(@times,100*SumDose(t1,t2,:)/RX_Dose,SliceMaskUr(t1,t2));
  4 comentarios
Mohsen
Mohsen el 18 de Jun. de 2013
I changed
DoseCubeU(m+(l-1)*iNX+i*iNY*iNX)=100*SumDose(m,l,i)/RX_Dose;
to
DoseCubeU(double(m)+double((l-1))*double(iNX)+double((i-1))*double(iNY)*double(iNX))=100*SumDose(m,l,i)/RX_Dose;
Otherwise the indexing will not be correct. For example, iNX*iNY*iNZ (which is 120*120*11) becomes equal to 65535 (which is wrong). We should write it as double(iNX)*double(iNY)*double(iNZ) in order to get the correct results (ie. 158400).
By making this change, both the indexing (the initial) method and the subscription method (below) give the same results. But these results are different than any of the other proposed methods.
So, how can I optimize:
for i=1:iNZ;
if iPointsinSlice>0;
for m=1:iNX;
for l=1:iNY;
if SliceMaskUr(m,l)==1;
DoseCubeU(m,l,i)=100*SumDose(m,l,i)/RX_Dose;
end
end
end
end
end
Andrei Bobrov
Andrei Bobrov el 19 de Jun. de 2013
Corrected. See ADD part in my answer.

Iain
Iain el 18 de Jun. de 2013
Try:
DoseCubeU(NY,NX,NZ) = 0; % or any suitable initialisation
if iPointsinSlice>0;
DoseCubeU(SliceMaskUr(m,l)==1,:) = 100*SumDose(SliceMaskUr(m,l)==1,:);
end
  2 comentarios
Mohsen
Mohsen el 18 de Jun. de 2013
This gives me a different answer than all the other four methods!
Mohsen
Mohsen el 18 de Jun. de 2013
I changed
DoseCubeU(m+(l-1)*iNX+i*iNY*iNX)=100*SumDose(m,l,i)/RX_Dose;
to
DoseCubeU(double(m)+double((l-1))*double(iNX)+double((i-1))*double(iNY)*double(iNX))=100*SumDose(m,l,i)/RX_Dose;
Otherwise the indexing will not be correct. For example, iNX*iNY*iNZ (which is 120*120*11) becomes equal to 65535 (which is wrong). We should write it as double(iNX)*double(iNY)*double(iNZ) in order to get the correct results (ie. 158400).
By making this change, both the indexing (the initial) method and the subscription method (below) give the same results. But these results are different than any of the other proposed methods.
So, how can I optimize:
for i=1:iNZ;
if iPointsinSlice>0;
for m=1:iNX;
for l=1:iNY;
if SliceMaskUr(m,l)==1;
DoseCubeU(m,l,i)=100*SumDose(m,l,i)/RX_Dose;
end
end
end
end
end

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by