Multiple loops issue in matlab - matlab

Sorry for asking really basic question but I am confused in multiple loops.
I want to run loops all at same time and then break the loop and go to next loop for R, e and x combine.
Means for R =1 ,e=1 ,x=1 and then R=2 ,e=2 ,x=2 and so on.
Can someone tell me where I am at fault or what is missing to get my desired results?
Code:
threshold = [0.4:0.1:1.1];
limit_for_idx = [0.4:0.1:1.1];
limit = [0.4:0.1:1.1];
D=1;
E=1;
J=0;
for R = 1:numel(threshold);
for e = 1:numel(limit_for_idx);
for x = 1:numel(limit)
J = J+1 ;
% Perform Tasks and go to next loop for R ,e and x
break
end
break
end
end

The wrong in your code is that in the 2nd iteration and so on, e and x will get 1 again, and not 2 or which value that you want.
To solve that, just iterate one variable and equal them all to it:
threshold = [0.4:0.1:1.1];
limit_for_idx = [0.4:0.1:1.1];
limit = [0.4:0.1:1.1];
D=1;
E=1;
J=0;
for R=1:numel(threshold)
e=R;
x=R;
% do your stuff...
end

Related

A conditional statement during a for loop in MATLAB

This is my attempt of a simple example (it seems pointless) but the idea is bigger than this simple code.
During a for loop, if something happens, I want to skip this step of the for loop and then add an extra step on the end.
I am trying to create a list of numbers, that do not include the number 8.
If the code creates an 8, this will mean that exitflag is equal to 1.
Can I adapt this program so that if the exitflag=1, the it will remove that result and add another loop.
The code:
for i = 1:1000
j = 1+round(rand*10)
if j == 8
exitflag = 1
else
exitflag = 0
end
storeexit(i)=exitflag;
storej(i)=j;
end
sum(storeexit)
I would ideally like a list of numbers, 1000 long which does not contain an 8.
If what you want to do is 1000 iterations of the loop, but repeat a loop iteration if you don't like its result, instead of tagging the repeat at the end, what you can do is loop inside the for loop until you do like the result of that iteration:
stores = zeros(1000,1); % Note that it is important to preallocate arrays, even in toy examples :)
for i = 1:1000
success = false; % MATLAB has no do..while loop, this is slightly more awkward....
while ~success
j = 1+round(rand*10);
success = j ~= 8;
end
storej(i) = j; % j guaranteed to not be 8
end
No.
With for loop, the number of loops is determined on the loop start and it is not dynamic.
For doing what you want, you need to use a while loop.

Matlab how to show progress in text showing up in command window

I am running a program that needs to take some time. It is better to show the running progress in real time, showing up in the command window. Something like below:
>>>>>>>> completed 90%
Assume the program runs though multiple loops:
for ii = 1:n
for jj = 1:m
for kk = 1:s
.....
end
end
end
Is there any efficient way or some special function to achieve that? I don't want to use waitbar.m since I also have other results printed in real time in the command window. These printed results, coupled with the texted progress, are used for the convenience of inspection.
First of all you need to compute the percentage step every time the inner loop advances. This can be done by computing:
percent_step = 1.0 / n / m / s
Then you can just force MATLAB to print on the same line by using a concatenation of \b (backspace character). Here is a MWE that just compute a random 10x10 matrix and get its transpose (just to show the percentage progress):
backspaces = '';
percentage = 0;
% DEFINE n, m, s as you wish, here I put some random values
n = 100;
m = 15;
s = 24;
percent_step = 100.0 / n / m / s;
for ii = 1:n
for jj = 1:m
for kk = 1:s
% Do stuff
a = rand(10);
b = a';
% Print percentage progress
percentage = percentage + percent_step;
perc_str = sprintf('completed %3.1f', percentage);
fprintf([backspaces, perc_str]);
backspaces = repmat(sprintf('\b'), 1, length(perc_str));
end
end
end
If you don't mind a progress display opening up in a separate window, you could use the Matlab waitbar.
For your example, say you wanted to compute a waitbar based on the number of iterations completed over the outer loop, it would be something like
h=waitbar(0, 'My waitbar');
for ii = 1:n
for jj = 1:m
for kk = 1:s
.....
end
end
fraction_done = ii/n;
waitbar(fraction_done)
end
close (h)
If you really want a text-based display, there is the waittext available on MATLAB File Exchange at https://www.mathworks.com/matlabcentral/fileexchange/56424-waittext.
I have not worked with this but it appears to be similar to what you wanted.

matlab code to prompt a user for input inside a loop

I was asked to write a matlab code to calculate the mean of 5 numbers utilizing a loop structure, I wrote this code but I was wondering if I could do something to make matlab ask me to enter the values in order 1 to 5, for example " Enter Value 1 " " Enter Value 2" , etc.
sumx = 0;
N = 5;
i=1;
for n =1:N
i=i+1;
Valuei=input('Enter Values= ');
sumx = sumx+Valuei;
end
Ybar=sumx/5;
display(Ybar);
You need sprintf:
N = 5;
for n = 1:N
prompt = sprintf('Enter Value %d=', n);
Value = input(prompt);
...
end
The %d is replaced by the value of n for each iteration of the loop.
Also, the variable i isn't used. You can get rid of it. It's a bad idea to use i (or j) as a variable name anyway since it's already defined by Matlab to be the imaginary unit.

Get final variable for a code with loops on Matlab

I have a code with two for loops. The code is working properly. The problem is that at the end I would like to get a variable megafinal with the results for all the years. The original varaible A has 3M rows, so it gives me an error because the size of the megafinal changes with each loop iteration and matlab stops running the code. I guess it’s a problem of inefficiency. Does anyone know a way to get this final variable despite of the size?
y = 1997:2013;
for i=1:length(y)
A=b(cell2mat(b(:,1))==y(i),:);
%Obtain the absolute value of the difference
c= cellfun(#minus,A(:,3),A(:,4));
c=abs(c);
c= num2cell(c);
A(:,end+1) = c;
%Delete rows based on a condition
d = (abs(cell2mat(A(:,8)) - cell2mat(A(:,7))));
[~, ind1] = sort(d);
e= A(ind1(end:-1:1),:);
[~, ind2,~] = unique(strcat(e(:,2),e(:, 6)));
X= e(ind2,:);
(…)
for j = 2:length(X)
if strcmp(X(j,2),X(j-1,2)) == 0
lin2 = j-1;
%Sort
X(lin1:lin2,:) = sortrows(X(lin1:lin2,:),13);
%Rank
[~,~,f]=unique([X{lin1:lin2,13}].');
g=accumarray(f,(1:numel(f))',[],#mean);
X(lin1:lin2,14)=num2cell(g(f));
%Score
out1 = 100 - ((cell2mat(X(lin1:lin2,14))-1) ./ size(X(lin1:lin2,:),1))*100;
X(lin1:lin2,15) = num2cell(out1);
lin1 = j;
end
end
%megafinal(i)=X
end
Make megafinal a cell array. This will account for the varying sizes of X at each iteration. As such, simply do this:
megafinal{i} = X;
To access a cell element, you just have to do megafinal{num}, where num is any index you want.

MATLAB: subtracting each element in a large vector from each element in another large vector in the fastest way possible

here is the code I have, its not simple subtraction. We want subtract each value in one vector from each value in the other vector, within certain bounds tmin and tmax. time_a and time_b are the very long vectors with times (in ps). binsize is just for grouping times in a similar range for plotting. The longest way possible would be to loop through each element and subtract each element in the other vector, but this would take forever and we are talking about vectors with hundreds of megabytes up to gb.
function [c, dt, dtEdges] = coincidence4(time_a,time_b,tmin,tmax,binsize)
% round tmin, tmax to a intiger multiple of binsize:
if mod(tmin,binsize)~=0
tmin=tmin-mod(tmin,binsize)+binsize;
end
if mod(tmax,binsize)~=0
tmax=tmax-mod(tmax,binsize);
end
dt = tmin:binsize:tmax;
dtEdges = [dt(1)-binsize/2,dt+binsize/2];
% dtEdges = linspace((tmin-binsize/2),(tmax+binsize/2),length(dt));
c = zeros(1,length(dt));
Na = length(time_a);
Nb = length(time_b);
tic1=tic;
% tic2=tic1;
% bbMax=Nb;
bbMin=1;
for aa = 1:Na
ta = time_a(aa);
bb = bbMin;
% tic
while (bb<=Nb)
tb = time_b(bb);
d = tb - ta;
if d < tmin
bbMin = bb;
bb = bb+1;
elseif d > tmax
bb = Nb+1;
else
% tic
% [dum, dum2] = histc(d,dtEdges);
index = floor((d-dtEdges(1))/(dtEdges(end)-dtEdges(1))*(length(dtEdges)-1)+1);
% toc
% dt(dum2)
c(index)=c(index)+1;
bb = bb+1;
end
end
% if mod(aa, 200) == 0
% toc(tic2)
% tic2=tic;
% end
end
% c=c(1:end-1);
toc(tic1)
end
Well, not a final answer but a few clue to simplify and accelerate your system:
First, use cached values. For example, in your line:
index = floor((d-dtEdges(1))/(dtEdges(end)-dtEdges(1))*(length(dtEdges)-1)+1);
your loop repeat the same computations every iteration. You can calculate the value before starting the loop, cache it then reuse the stored result:
cached_dt_constant = (dtEdges(end)-dtEdges(1))*(length(dtEdges)-1) ;
Then in your loop simply use:
index = floor( (d-dtEdges(1)) / cached_dt_constant +1 ) ;
if you have so many loop iteration you'll save valuable time this way.
Second, I am not entirely sure of what the computations are trying to achieve, but you can save time again by using the indexing power of matlab. By replacing the lower part of your code like this, I get an execution time 2 to 3 time faster (and the same results obviously).
Na = length(time_a);
Nb = length(time_b);
tic1=tic;
dtEdge_span = (dtEdges(end)-dtEdges(1)) ;
cached_dt_constant = dtEdge_span * (length(dtEdges)-1) ;
for aa = 1:Na
ta = time_a(aa);
d = time_b - ta ;
iok = (d>=tmin) & (d<=tmax) ;
index = floor( (d(iok)-dtEdges(1)) ./ cached_dt_constant +1 ) ;
c(index) = c(index) +1 ;
end
toc(tic1)
end
Now there is only one loop to go through, the inner loop has been removed and replaced by vectorized calculation. By scratching the head a bit further there might be a way to do even without the top loop and use only vectorized computations. Although this will require to have enough memory to handle quite big arrays in one go.
If the precision of each value is not critical (I see you round and floor values often), try converting your initial vectors to 'single' type instead of the default matlab 'double'. that would almost double the size of array your memory will be able to handle in one go.