How to compute the number of operations of jacobi iteration in matlab - matlab

I want to compute the number of operations of jacobi iteration in matlab
I do not know how to do it !!!
Can you help me ?
Thanks
Here is my code for newton method :
b=zeros(30,1);
b(6)=2;
alpha=1;
A=zeros(30,30);
A(1,1)=-(2+alpha);
A(1,2)=1;
for ii=2:29
A(ii,ii-1)=1
A(ii,ii)=-(2+alpha)
A(ii,ii+1)=1
end
A(30,29)=1;
A(30,30)=-(2+alpha);
D=diag(diag(A));
R=A-D;
x=zeros(30,1);
for ii=1:100
xk= inv(D)*(b-R*x);
if(norm(xk-x,1)<=10^-5)
break;
end
x=xk;
end
ii

You have counted it, actually.
In case of code
for ii=1:N
%% Code
end
the ii variable works like the counter.
Reading the code step-by-step you:
Define anonymous temporary array, say forII with elements 1 to N with default step of 1.
For each iteration the appropriate element of original forII is assigned to ii
%% Code is executed
New value of ii scalar is assigned.
This behaviour allows:
Use counter=1:N as true counter.
Loop easily over elements of any array, for example for foo='Hello World!'.
Use predefined indices, array elements, etc. for ii=A.
When the for loop is terminated by break or return prompt the elements in queue are not assigned and ii keeps the last assigned value.
You can try
kk=0;
for ii=1:N
kk=kk+1;
if ii==5
break
end
end
disp(['kk = ' num2str(kk) '; ii = ' num2str(ii)]);
kk=0;
for ii='Hello World!'
kk=kk+1;
if ii=='r'
break
end
end
disp(['kk = ' num2str(kk) '; ii = ' num2str(ii)]);

Related

MATLAB - plot an iteration

The code so far:
function [fr]=frictionFactorFn(rho,mu,e,D,L,Q,f0,tol,imax)
format long
CS=(pi*D^(2))/4;%Cross sectional area of pipe
v=Q/CS;%velocity
Re=(rho*v*L)/mu;
iter=1;i=1;fr(1)=f0;
while 1
fr(i+1)=(-1.74*log((1.254/(Re*sqrt(fr(i))))+((e/D)/3.708)))^-2;%substitution for root finding
iter=iter+1;
if abs(fr(i+1)-fr(i))<tol || iter>=imax
break;
end
i=i+1;
end
fprintf('\n The Reynolds number is %f\n',Re);
plot(0:iter-1,fr);
xlabel('Number of iteration'),ylabel('friction factor');
end
It gave me the right converged value of f=0.005408015, but I would like to plot the iteration
Possibly by storing the values of f upon each iteration in an array. In this example the array is called Store_f and is plotted after the while-loop is completed. The variable Index below is used to indicate which cell of array Store_f the value should be saved to.
function [f_vals] = frictionfactorfn()
Index = 1;
while (Condition)
%Calculation code%
Store_f(Index) = f;
Index = Index + 1;
end
disp(num2str(f))
plot(Store_f,'Marker','.');
xlabel('Iteration'); ylabel('Value');
end

How to correct "Valid indices for 'variable' are restricted in PARFOR loops" error in matlab

I am trying to set up a parfor nested loop in MatLab R2016a as below.
N = size(A,1);
M = size(v,1);
in = zeros(N*M,1);
parfor i=1:N
for j=1:M
k = (i-1)*M+j;
if sqrt(sum((A(i,:)-v(j,:)).^2))<=tol
in(k) = i;
end
end
end
However, I am getting the following error Valid indices for 'in' are restricted in PARFOR loops. Is there some way I can correct this because both arrays A and v are considerably large, over 40,000 rows for A and 8,000 v? The variable tol is 0.0959.
The problem is that MATLAB doesn't recognize that the variable k is slicing the matrix in correctly. The solution should be to index in using i and j separately:
N = size(A,1);
M = size(v,1);
in = zeros(M,N);
parfor i=1:N
for j=1:M
if sqrt(sum((A(i,:)-v(j,:)).^2))<=tol
in(j,i) = i;
end
end
end
in = in(:); % reshape to a column vector, as the output in the question's code
The other alternative, but it requires more intermediate memory, is to compute this without a loop at all:
A = reshape(A,1,N,[]);
v = reshape(v,M,1,[]);
in = sum(bsxfun(#minus,A,v).^2,3) < tol*tol;
in = in(:);
(Or something similar to that, I have not run this code... Please let me know, or fix the post, if there is a typo or other mistake.)
N = size(A,1);
M = size(v,1);
in = cell(N,1);
parfor i=1:N
s=v;
p=zeros(1:M,1);
for j=1:M
k = (i-1)*M+j;
if sqrt(sum((A(i,:)-s(j,:)).^2))<=tol
p(k) = i;
end
end
in{i}=single(p);
end
in=cell2mat(in);
in=reshape(in,[N*M,1]);
sometime matlab doesnt recognize a variable in parfor loop as "sliced variable"
, a sliced variable is a variable that has a reference out of parfor loop and each of its element only accessed by a single worker (in parfor parallel workers)
so you could use a temporary variable and collect results after the parfor loop,
NOTE 1: It is better to vectorise code in the older versions because loops didn't use to be as good as they are now in R2017 referring to (this).
NOTE 2: if most elements of "in" are zero try using "sparse matrix" which could save a lot of memory;

While loop inside for loop in Matlab

I am trying to using a while loop inside a for loop in Matlab. The while loop will repeat the same action until it satifies some criteria. The outcome from the while loop is one iteration in the for loop. I am having a problem to get that correctly.
n=100;
for i=1:n
while b<0.5
x(i)=rand;
b=x(i);
end
end
I am not sure what i am doing wrongly.
Thanks
Approach the problem differently. There's no need to try again if rand doesn't give you the value you want. Just scale the result of rand to be in the range you want. This should do it:
x = 0.5 + 0.5*rand(1, 100);
With the example you showed, you have to initialize b or the while-statement cannot be evaluated when it is first called.
Do it inside the for-loop to avoid false positives after the first for-iteration:
n=100;
for ii=1:n
b = 0;
while b<0.5
x(ii)=rand;
b=x(ii);
end
end
Or, without b:
n=100;
x = zeros(1,100);
for ii=1:n
while x(ii)<0.5
x(ii)=rand;
end
end

How to count the number of iterations

I'm working with k-means on MATLAB. To process the valid cluster, it needs to do a looping until the cluster position doesn't change any more. The looping will show the iterations process.
I want to count how many looping/iteration happens on that clustering process. Here is the snippet of looping/iteration processing part:
while 1,
d=DistMatrix3(data,c); %// calculate the distance
[z,g]=min(d,[],2); %// set the matrix g group
if g==temp, %// if the iteration does not change anymore
break; %// stop the iteration
else
temp=g; %// copy the matrix to the temporary variable
end
for i=1:k
f=find(g==i);
if f %// calculate the new centroid
c(i,:)=mean(data(find(g==i),:),1);
end
end
end
All I know that I have to do is define the iteration variable, and then write the calculation part. But, where do I have to define the variable? And how?
All the answers will be so much appreciated.
Thank you.
A Matlab while-loop is executed until the expression is false. The general setup is like this:
while <expression>
<statement>
end
If you want to count the number of times the while loop was entered, the easiest way is to declare a variable outside the loop and incrementing it inside:
LoopCounter = 0;
while <expression>
<statement>
LoopCounter = LoopCounter + 1;
end
The question whether to increment the LoopCounter before or after the <statement> depends on whether you need it to access vector entries. In that case, it should be incremented before the <statement> because 0 is not a valid index in Matlab.
Define before your loop, update in your loop.
iterations=0;
while 1,
d=DistMatrix3(data,c); % calculate the distance
[z,g]=min(d,[],2); % set the matrix g group
if g==temp, % if the iteration doesn't change anymore
break; % stop the iteration
else
temp=g; % copy the matrix to the temporary variable
end
for i=1:k
f=find(g==i);
if f % calculate the new centroid
c(i,:)=mean(data(find(g==i),:),1);
end
end
iterations=iterations+1;
end
fprintf('Did %d iterations.\n',iterations);

How do I know how many iterations are left in a parfor loop in Matlab?

I am running a parfor loop in Matlab that takes a lot of time and I would like to know how many iterations are left. How can I get that info?
I don't believe you can get that information directly from MATLAB, short of printing something with each iteration and counting these lines by hand.
To see why, recall that each parfor iteration executes in its own workspace: while incrementing a counter within the loop is legal, accessing its "current" value is not (because this value does not really exist until completion of the loop). Furthermore, the parfor construct does not guarantee any particular execution order, so printing the iterator value isn't helpful.
cnt = 0;
parfor i=1:n
cnt = cnt + 1; % legal
disp(cnt); % illegal
disp(i); % legal ofc. but out of order
end
Maybe someone does have a clever workaround, but I think that the independent nature of the parfor iterations belies taking a reliable count. The restrictions mentioned above, plus those on using evalin, etc. support this conclusion.
As #Jonas suggested, you could obtain the iteration count via side effects occurring outside of MATLAB, e.g. creating empty files in a certain directory and counting them. This you can do in MATLAB of course:
fid = fopen(['countingDir/f' num2str(i)],'w');
fclose(fid);
length(dir('countingDir'));
Try this FEX file: http://www.mathworks.com/matlabcentral/fileexchange/32101-progress-monitor--progress-bar--that-works-with-parfor
You can easily modify it to return the iteration number instead of displaying a progress bar.
Something like a progress bar could be done similar to this...
Before the parfor loop :
fprintf('Progress:\n');
fprintf(['\n' repmat('.',1,m) '\n\n']);
And during the loop:
fprintf('\b|\n');
Here we have m is the total number of iterations, the . shows the total number of iterations and | shows the number of iterations completed. The \n makes sure the characters are printed in the parfor loop.
With Matlab 2017a or later you can use a data queue or a pollable data queue to achieve this. Here's the MathWorks documentation example of how to do a progress bar from the first link :
function a = parforWaitbar
D = parallel.pool.DataQueue;
h = waitbar(0, 'Please wait ...');
afterEach(D, #nUpdateWaitbar);
N = 200;
p = 1;
parfor i = 1:N
a(i) = max(abs(eig(rand(400))));
send(D, i);
end
function nUpdateWaitbar(~)
waitbar(p/N, h);
p = p + 1;
end
end
End result :
If you just want to know how much time is left approximately, you can run the program once record the max time and then do this
tStart = tic;
parfor i=1:n
tElapsed = toc(tStart;)
disp(['Time left in min ~ ', num2str( ( tMax - tElapsed ) / 60 ) ]);
...
end
I created a utility to do this:
http://www.mathworks.com/matlabcentral/fileexchange/48705-drdan14-parforprogress