I have executed this simple loop script in MATLAB
clc;clear; close all;
m = 100;
for i = 1:m
if(i == 2)
m = 1000;
end
end
and found, that 'i' loops only till '100' BUT NOT '1000'. Why..??
The statement for i=1:m assigns the array 1:m to the list of values the operator will take on during the loop. This happens when the loop starts executing (note: you can use any array, and it'll be worked through column by column; for letter='abcde';fprintf('%s\n',letter);end works fine).
If you want to adjust how often your loop will be iterated through, I recommend using a while loop:
ct = 1;
maxIterations = 100;
success = false;
while ~success
fprintf('iteration %i/%i\n',ct,maxIterations);
ct = ct + 1;
if ct == 2
maxIterations == 1000;
end
if ct > maxIterations
success = true;
end
end
I'm not an expert but the for loop replace the m var with 100 in the first run and then it performs the loop as from 1 to 100 (not 1 to m) and it doesnt check every run what is m it knows that m is 100 and it runs until it reaches 100 if for example your script is like this:
<code>
m=100;
for i=1:m (m is 100)
if(i==2)
m=1000;
for i=1:m (m is 1000)
a=xyz;
end
end
end
</code>
Related
I defined two same size vectors t and coverage in Matlab, and I need to define a third vector n_steps.
In particular I need to speed up the following loop:
t = 1:100000;
coverage = double(rand(size(t)) > 0.9);
for j=1:(length(t)-1)
n_steps(j)=0;
while coverage(j+n_steps(j)+1)==0 && j+n_steps(j)+1<length(t)
n_steps(j)=n_steps(j)+1;
end
end
t is a time vector, and coverage at each time step can be 1 or 0.
For each instant t(j) I must find the number of time steps n_steps(j) to wait before the first 1 appears in the vector coverage(j+1:length(coverage)),
Your code (with the example data I added to it) runs in 0.0163 s on MATLAB Online. Just adding
n_steps = zeros(1,length(t)-1);
before the loop reduces the execution time to 0.0057 seconds. Preallocation is very important!
Next, I was able to change your code a bit, such that you don't need to search through the same array over and over again:
n_steps = zeros(1,length(t)-1);
cov = [find(coverage), length(t)];
k = 1;
for j=1:(length(t)-1)
if cov(k) <= j
k = k+1;
end
n_steps(j) = cov(k) - j - 1;
end
This code runs in 0.0015 seconds. It relies on creating a smaller array, cov, that contains the indices to non-zero elements in coverage. cov(k) is the index into coverage for a non-zero element. As we move j forward, sometimes we need to move the index k forward too, such that cov(k) comes after j.
It might be possible to further vectorize the outer loop, but I doubt it will make the code much faster.
This is the script I wrote for timing and testing correctness:
t = 1:100000;
coverage = double(rand(size(t)) > 0.9);
timeit(#() method1(t, coverage))
timeit(#() method2(t, coverage))
timeit(#() method3(t, coverage))
a = method1(t, coverage);
b = method3(t, coverage);
assert(isequal(a,b))
function n_steps = method1(t, coverage)
for j=1:(length(t)-1)
n_steps(j)=0;
while coverage(j+n_steps(j)+1)==0 && j+n_steps(j)+1<length(t)
n_steps(j)=n_steps(j)+1;
end
end
end
function n_steps = method2(t, coverage)
n_steps = zeros(1,length(t)-1);
for j=1:(length(t)-1)
while coverage(j+n_steps(j)+1)==0 && j+n_steps(j)+1<length(t)
n_steps(j) = n_steps(j)+1;
end
end
end
function n_steps = method3(t, coverage)
n_steps = zeros(1,length(t)-1);
cov = [find(coverage), length(t)];
k = 1;
for j=1:(length(t)-1)
if cov(k) <= j
k = k+1;
end
n_steps(j) = cov(k) - j - 1;
end
end
I'm using a code that calculates expectation value of probabilities. This code contains a while-loop that finds all possible combinations and adds up products of probability combinations. However, when the number of elements becomes large(over 40) it takes too much time, and I want to make the code faster.
The code is as follow-
function pcs = combsum(N,K,prbv)
nprbv=1-prbv; %prbv: probability vector
WV = 1:K; % Working vector.
lim = K; % Sets the limit for working index.
inc = 0; % Controls which element of WV is being worked on.
pcs = 0;
stopp=0;
while stopp==0
if logical((inc+lim)-N)
stp = inc; % This is where the for loop below stops.
flg = 0; % Used for resetting inc.
else
stp = 1;
flg = 1;
end
for jj = 1:stp
WV(K + jj - inc) = lim + jj; % Faster than a vector assignment.
end
PV=nprbv;
PV(WV)=prbv(WV);
pcs=prod(PV)+pcs;
inc = inc*flg + 1; % Increment the counter.
lim = WV(K - inc + 1 ); % lim for next run.
if (inc==K)&&(lim==N-K)
stopp=1;
WV = (N-K+1):N;
PV=nprbv;
PV(WV)=prbv(WV);
pcs=prod(PV)+pcs;
end
end
Is there a way to reduce calculation time? I wonder if parallel computing using GPU would help.
I tried to remove dependent variables in a loop for parallel computing, and I made a matrix of possible combinations using 'combnk' function. This worked faster.
nprbv=1-prbv; %prbv : a probability vector
N = 40;
K = 4;
n_combnk = size(combnk(1:N,K),1);
PV_mat = repmat(nprbv,n_combnk,1);
cnt = 0;
tic;
for i = 1:N-K+1
for j = i+1:N-K+2
for k = j+1:N-K+3
for l = k+1:N-K+4
cnt = cnt+1;
PV_mat(cnt,i) = prbv(i);
PV_mat(cnt,j) = prbv(j);
PV_mat(cnt,k) = prbv(k);
PV_mat(cnt,l) = prbv(l);
end
end
end
end
toc;
tic;
pcs_rr = sum(prod(PV_mat,2));
toc;
However, when K value gets larger, an out-of-memory problem happens in building a combination matrix(PV_mat). How can I break up the big matrix into small ones to avoid memory problem?
I have written a function that estimates the inverse of e and loops through values of n until the approximated value is within a given tolerance of the actual value.
Currently I use this code:
function [approx, n] = calc_e(tolerance)
for n = 1:inf
approx = ((1-1/n)^n);
diff = (1/exp(1)) - approx;
if diff < tolerance, break; end
end
end
This works fine however I have been told that it could be more efficient by using a while loop but I can't work out how to do it in that way.
Can anybody shed some light on this?
Simply do:
function [approx, n] = calc_e(tolerance)
n = 1;
while (1/exp(1)) - ((1-1/n)^n) >= tolerance
n = n + 1;
end
end
Here is my sample code, made to work out how to get a while loop to end when any one of three conditions are satisfied.
I want the code to end when n = 100, but it ends at n = 301. How can I get this to end at n=100?
clear all; close all;
n = 0;
R = 0; A = 0; T = 0;
while (R~=1) || (A~=1) || (T~=1)
if n == 100
R = 1;
end
if n == 200
A = 1;
end
if n == 300
T = 1;
end
n=n+1;
end
|| means or (with short circuiting). This means that your loop won't quit until all of the conditions are false.
You want to use AND, which is &&. This will mean the loop quits when at least one of the conditions is false.
ALSO (from the comments below):
Currently n will have a value of 101 when the loop finishes (because of the n=n+1 at the bottom of the loop). If it was important that the value of n was 100, then you could insert a break (info here) into the if body so that the loop quit when n = 100.
I run this code:
for i=1:length(matr)
...where matr is square matrix. In this loop the size of the matr changes, but it seems that the loop continues to run, until i doesn't not exceed the initial value of length(matr)
How to maintain the fresh of length(matr) in the loop's condition?
Here is my code.
for i=1:length(matr1)
for j=1:length(matr1)
if((i~=j)&&(ismember(i,ind3)==0)&&(ismember(j,ind3)==0))
if (i>length(matr1))||(j>length(matr1))
continue
end
ind1 = find_tree(matr1,i);
ind2 = find_tree(matr1,j);
b = is_isomorphic(matr1(ind1,ind1),matr1(ind2,ind2),encode(ind1),encode(ind2));
if b,
number = number + length(ind1);
matr1(ind2,:) = [];
matr1(:,ind2) = [];
ind3 = find(summ_rows==-1);
end
end
end
end
I was managed to add
`if (i>length(matr1))||(j>length(matr1))`,
...because i and j exceeded the dimensions of the matrix.
You should be using a while loop:
ii = 0;
while(ii <= length(matr))
ii = ii + 1;
%// Your loop code here: e.g. the following line that alters the size of matr
matr = rand(randi(20) + 10);
end