As you know, using loops with big size matrix results delay, in my case I need to free my code of loops for the same reason(delay). This is my code example:
for i=1:n
for j=1:m-1
Z=A(i,j);
Z2= A(i,j+1);
if X(Z,Z) == X(Z2,Z)
X(Z2,Z) = X(Z2,Z)+1;
end
end
end
So, are there any suggestion? Many thanks.
Related
I'm trying to run this code in Matlab
a = ones(4,4);
b=[1,0,0,1;0,0,0,1;0,1,0,0;0,0,0,0];
b(:,:,2)=[0,1,1,0;1,1,1,0;1,0,1,1;1,1,1,1];
parfor i = 1:size(b,3)
c = b(:,:,i)
a(c) = i;
end
but get the error:
Error: The variable a in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
There are restrictions in how you can write into arrays inside the body of a parfor loop. In general, you will need to use sliced arrays.
The reason behind this issue is that Matlab needs to prevent that different worksers access the same data, leading to unpredictable results (as the timely order in which the parfor loops through i is not detemined).
So, although in your example the workers don't operate on the same entries of a, due to the way how you index a (with an array of logicals), it is currently not possible for Matlab to decide if this is the case or not (in other words, Matlab cannot classify a).
Edit: For completeness I add some code that is equivalent to your example, although I assume that your actual problem involves more complicated logical indexing?
a = ones(4,4,4);
parfor i = 1:size(a,1)
a(i, :, :) = zeros(4, 4) + i; % this is sliced indexing
end
Edit: As the OP example was modified, the above code is not equivalent to the example anymore.
I am a newbie to Matlab and I am currently trying to optimize a nested for loop as below. The loop is currently running forever for my input.
for i = 1:size(mat,1)
for j = 1:size(mat,2)
mat(i,j) = some_mapping(mat(i,j)+1);
end
end
However I can't find a way to vectorize it. I have tried bsxfun and arrayfun but it does not seem to work (or even run more slowly than the loop).
Maybe I was doing it in a wrong way. Any help is appreciated!
As suggested by Andras Deak, if some_mapping is simply a look-up-table operation, then
mat = some_mapping( mat+1 );
Notes:
- In order of the mapping to work, the values of mat must be integers in the range [0..numel(some_mapping)-1].
- The size of some_mapping does not affect the size of the result, it will be identical in size to mat.
I have a problem with the following code. I want to store all the values I am creating in the for loop below so that I can make a plot of it. I have tried several things, but nothing works. Does anyone know a simple method to create a vector of the results and then plot them?
dx=0.1;
t=1;
e=1;
for x=-1:dx:1
lower_bound=-100;
upper_bound=x/(sqrt(4*t*e));
e=1;
u=(1/sqrt(pi))*quad(#integ,lower_bound,upper_bound);
plot(x,u)
hold on
end
hold off
I would like to use as much of this matlab code as possible.
dx=0.1;
t=1;
e=1;
xval=[-1:dx:1].';
upper_bound = zeros(numel(xval),1);
u = zeros(numel(xval),1);
for ii=1:numel(xval)
x = xval(ii)
lower_bound=-100;
upper_bound(ii,1)=x/(sqrt(4*t*e));
u(ii,1)=(1/sqrt(pi))*quad(#integ,lower_bound,upper_bound(ii));
end
figure;
plot(xval,u)
by adding the (ii) behind your statements it saves your variables in an array. I did not use that on your lower_bound since it is a constant.
Note that I first created an array xval and called that with integers in ii, since subscriptindices must be positive integers in MATLAB. I also initialised both upper_bound and u by creating a zero matrix before the loop executes. This is handy since extending an existing vector is very memory and time consuming in MATLAB and since you know how big they will get (same number of elements as xval) you might as well use that.
I also got the plot call outside the loop, to prevent you from plotting 21 blue lines in 1 plot.
I am implementing an Sum of Square Distances based disparity Map function in Matlab for computer vision. Currently the code has a nested for loop and runs very slow. Any suggestions on vectorizing it to make it more efficient? Thanks
%im1 and im2 are images and win1, win2 are window sizes
for i=win1+1:1:bottom-win1
parfor j=win2+1:1:right-win2
%j=[win2+1:bottom-win2];
template=im1(i-win1:i+win1,j-win2:j+win2);
arg1=conv2(im2.^2,ones(size(template))/2,'same');
arg2=conv2(im2,rot90(template,2),'same');
arg=arg1-arg2;
[xj]=find(arg==min(arg(:)));
disparityMap(i,j)=1-xj(1);
end
end
Three suggestions to try to speed things up:
move the parfor to the outer loop to reduce the overhead of the parallel construct ;
compute im2.^2 once before the loop and save its value in a temporary variable as it does not depend on the loop variables there is no need to compute it again and again, and actually
move the whole computation of arg1 out of the loops as it only depends on the size of template and not its value, and if I see correctly, the size is constant ;
replace the [xj]=find(arg==min(arg(:))); construct with something along the lines of [tmp, ind] = min(arg(:)) ; xj=ind2sub(size(arg), ind) to avoid the call to find and rescan the matrix while the indices can be computed simply.
Untested, but it should give you a start
arg1=conv2(im2.^2,ones([2*win1+1, 2*win2+1])/2,'same');
parfor i=win1+1:1:bottom-win1
for j=win2+1:1:right-win2
%j=[win2+1:bottom-win2];
template=im1(i-win1:i+win1,j-win2:j+win2);
arg2=conv2(im2,rot90(template,2),'same');
arg=arg1-arg2;
[tmp, ind] = min(arg(:)) ;
xj=ind2sub(size(arg), ind);
disparityMap(i,j)=1-xj(1);
end
end
Also make sure the number of workers is chosen appropriately, and try to compile the code to mex to see if there is improvement.
I don't understand this piece of code of a for loop in matlab, I know that loops in matlab usually look like: for ii=1:2:100 so that it starts in 1 until 100 and in each iteration you add 2.
But here I've got this condition in the loop and I don't get what it does:
for ii=[1:w:rd(1)-w-border, rd(1)-w-border+1],
...
end;
w and border are integers passed as arguments and rd is size of the image/matrix (rd = size(image);)
Can someone explain me how for loops work in matlab with this kind of condition?
Thanks in advance.
For loop in matlab can execute statements for a defined set of index values:
For example, the following code will display all the element in the set [1,5,8,17]:
for s = [1,5,8,17]
disp(s)
end
Your code for ii=[1:w:rd(1)-w-border, rd(1)-w-border+1] is similar.
Its just like a set 1:w:rd(1)-w-border with an additional element rd(1)-w-border+1.
Its like writing this set [1,2,3,4,5,8] as [1:1:5, 8]
I hope its clear now.
the for argument is a vector. the loop iterator ii takes one value for the vector for each iteration of the loop. As you mentioned, the vector can be equally spaced one like 1:2:100. But it can also be arbitrary, for example for ii = [4,6,1,8] ....
In you case the for argument vector is partly "equally spaced" vector: 1:w:rd(1)-w-border plus another element rd(1)-border+1.