How to get the output of a function handle after called afterEach in Matlab? - matlab

I try to update the value of a variable once it receive a data, so that I could update the message on waitbar on how many jobs it has completed. My code looks something like this:
function value = completedJobs(value)
value=value+1;
end
job=0;
dq = parallel.pool.DataQueue;
wb = waitbar(0,'Processing');
afterEach(dq, #(varargin) completedJobs(job)) // this is where I would like to update the waitbar with new completed jobs on the message
afterEach(dq, #(varargin) waitbar(job,sprintf('Completed: %d', job));
parfor i=1:100
send(dq, i);
end
And is it possible to merge twice calling of the afterEach into only one that could perform what those two calling did?
Thanks in advance!

This should do the trick. Make sure you move the completedJobs function to its own script otherwise the clear function on line 1 won't work.
clear completedJobs
dq = parallel.pool.DataQueue;
wb = waitbar(0,'Processing');
Listener = afterEach(dq, #(varargin) waitbar((completedJobs/100),wb,sprintf('Completed: %d', completedJobs(1))));
parfor i=1:100
send(dq, i);
end
delete(wb);
Because the completedJobs function is called twice for every listened event you need to have a switch within the function to ensure that n is only incremented once. This is done by passing a dummy input to completedJobs
function j = completedJobs(varargin)
persistent n
if isempty(n)
n = 0;
end
if numel(varargin) ~=0
else
n = n+1;
end
j=n;
end

Related

What is the different between Break and Return? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have two Matlab codes that I want to determine a matrix is symmetric or not? I have used nested "for loops". Furthermore:
In the first code, I've got to exit of the program twice
''break''.
In the second code, I've got the command ''Return'' to
exit of the program.
Is there any problems between the Break and Return?
I have attached my codes.
First code:
clc
clear all
A=input('Please enter your matrix=')
n=length(A);
temp=0;
for i=1:n-1
for j=i+1:n
if A(i,j)~=A(j,i)
temp=1;
break
end
end
if temp==1
disp('Matrix A is not symmetric.')
break
end
end
Second code:
clc
clear all
A=input('Please enter your matrix=')
n=length(A);
temp=0;
for i=1:n-1
for j=i+1:n
if A(i,j)~=A(j,i)
disp('Matrix A is not symmetric.')
return
end
end
end
There are currently no issues in the code that you have posted. Here is a little bit of an elaboration on MATLAB's own documentation that will hopefully clear things up a bit for you.
According to the documentation, break will break out of a for or while loop:
break terminates the execution of a for or while loop. Statements in the loop after the break statement do not execute.
In nested loops, break exits only from the loop in which it occurs. Control passes to the statement that follows the end of that loop.
For example the following will only break out of the innermost loop.
for k = 1:3
fprintf('k = %d\n', k);
for m = 1:4
fprintf('m = %d\n', m);
% Will go back and evaluate the loop using the next k
break
end
end
This will print
k = 1
m = 1
k = 2
m = 1
k = 3
m = 1
To break out of both loops you would need a second break in the outer loop as well.
for k = 1:3
fprintf('k = %d\n', k);
for m = 1:4
fprintf('m = %d\n', m);
% Will go back and evaluate the loop using the next k
break
end
% Continue executing code after the for loop
break
end
disp('This will still execute')
This will print
k = 1
m = 1
This will still execute
On the other hand, return will break out of a function.
return forces MATLABĀ® to return control to the invoking function before it reaches the end of the function. The invoking function is the function that calls the script or function containing the call to return. If you call the function or script that contains return directly, there is no invoking function and MATLAB returns control to the command prompt.
This means that return will completely exit out of a function (whether it is inside of a loop or not).
function looper()
for k = 1:3
fprintf('k = %d\n', k);
for m = 1:4
fprintf('m = %d\n', m);
% No more iterations of ANY loop will be executed
return
end
end
disp('This will not execute')
end
This will print
k = 1
m = 1
No. There are no problems in using either. It depends completely on the purpose.
break terminates the execution of a for or while loop. Statements in the loop after the break statement do not execute.
In nested loops, break exits only from the loop in which it occurs. Control passes to the statement that follows the end of that loop. It retains the control in the outer block of the loop.
return forces MATLAB to return control to the invoking function before it reaches the end of the function. The invoking function is the function that calls the script or function containing the call to return. If you call the function or script that contains return directly, there is no invoking function and MATLAB returns control to the command prompt.
Within conditional blocks, such as if or switch, or within loop control statements, such as for or while, a return statement does not just exit the loop; it exits the script or function and returns control to the invoking function or command prompt.
In a nested loop control, break breaks out of the loop it is placed and continues the outer loop.

Matlab gui with pause function

I am using the GUIDE for matlab gui.
The gui built in order to communicate with keithley current measurement device through GPIB.
When using a toggle button for Current measurement while loop, i am using a pause() function inside the while loop for each iteration and a ytranspose on the y array reading results.
function Measure_Callback(hObject, eventdata, handles)
global GPIB1
global filename
global timeStep
disp('Measurement in progress \n stopwatch starts!');
tic
x=0;
n=0;
while get(hObject,'Value')
fprintf(GPIB1, 'printnumber(smua.measure.i(smua.nvbuffer1))');
fprintf(GPIB1, 'printbuffer(1,1,nvbuffer1)');
A = fscanf(GPIB1);
if length(A)<20
x = x+1;
n = n+1;
t(n) = toc ;
y(x) = str2double(A);
plot(t,y,'-bo',...
'LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[.49 1 .63],...
'MarkerSize',10);
grid on
hold on
end
title('Current vs Time','FontSize', 15)
xlabel('Time [s]','FontSize', 15)
ylabel('Current [A]','FontSize', 15)
a = timeStep;
pause(a)
end
disp('Measurement terminated');
disp('Elapsed time: ');
elapsedtime = toc;
elapsedtime_string = num2str(elapsedtime);
disp(elapsedtime_string);
ytrans = transpose(y);
csvwrite(filename,ytrans);
fprintf(GPIB1, 'smua.source.output = smua.OUTPUT_OFF');
For the pause function i'm geting error:
?? Error using ==> pause Error while evaluating uicontrol Callback
For the transpose(y) function i'm also getting a error:
its undefined y.
Cant understand why are those errors and could use some help.
Thank you!
First off, as people say, post the errors and the code. Do you know if length(A) is smaller than 20 in the first time you run the loop? Because if not, A is not defined and you can't transpose something that is not there. Initialize A before the loop to something and see if the error persists (or print out length(A) to make sure the loop gets entered the first run).
As for the pause error, make sure pause is an int or double, not a string. If you get your global timeStep from the GUI field, it is probably a string and you need to covert it to double first.

Check Position with for loop, not enough input arguments - Matlab

I made a simple function that loops between the rows and columns of an array using for loops. The loop is part of a function named checktakentest (Since I'm testing this method atm). I keep getting the error that there aren't enough input arguments.
function [spotTaken] = checktakentest(tttArray)
for h = 1:3
if tttArray(h,j) == 1
%Is spot is taken, break loop
spotTaken = 1; break;
else
spotTaken = 0;
end
for j=1:3
if tttArray(h,j) == 1
spotTaken = 1; break;
else
spotTaken = 0;
end
end
end
I tried also defining h and j previously as follows
h = [1,2,3];
j = [1,2,3];
Note that tttArray is a global variable defined in another function and its array values change in that function. A spot taken is 1, empty is 0. What arguments should I pass to the function and how do I know which ones to pass since this has been a recurring problem for me? A simple explanation would be appreciated. Note that I call the function via
checktakentest(tttArray)
Just remove the first if clause - at that point you don't have j initialized to a value, so you can't use it, yet:
function [spotTaken] = checktakentest(tttArray)
for h = 1:3
for j=1:3
if tttArray(h,j) == 1
spotTaken = 1; break;
else
spotTaken = 0;
end
end
end
If you call your function like this: checktakentest(tttArray) with tttArray beeing a mxn-matrix with m>2 and n>2 you should not get an error.
If you call it like this: checktakentest you will get the error you described (not enough input arguments).

Matlab - Do action after every line

Is there an elegant way to tell matlab to perform a predefined action after the execution of every line in a certain script? By elegant I mean no calling of the action after every line, but rather something like a simple command given at the start of the script.
Example:
Action --> disp('Performing Action');
script:
a = 1;
b = 2;
c = 3;
So the desirable outcome is that after each assignment (of a, b and c), the disp() command would be performed.
You can automatically create a modifed file that has the desired action included at the end of each line:
action = 'disp(''Performing Action'');'; %// action to be added at the end of each line
file = 'script.m'; %// original script
file_out = 'script_out.m'; %// modified script with action added
x = importdata(file); %// cell array of strings. Each line of the
%// original file is a string
x = strcat(x, {' ; '}, action); %// add action at the end of each string,
%// preceded with `;` in case the original line
%// didn't include that
fid = fopen(file_out, 'w');
fprintf(fid, '%s\n', x{:}); %// write output file
fclose(fid);
a = 1;
disp('Performing Action');
b = 2;
disp('Performing Action');
c = 3;
disp('Performing Action');
Or, if you can do this in a loop
for ii = 1:3
a(ii) = ii;
disp('Performing Action');
end
Actually making it output something after every line is not very matlab, but you could of course just loose all the semicolons and thus make it display all variables if you want to track where in the script you are.
I'd suggest a verbose switch in your code. Set it to 0 for no output and 1 for output (or use multiple levels if so desired)
if verbose > 0
disp('Performing Action');
end
This way you can easily switch the output on or off, depending on need.
For the code-reading and appending piece, see Louis Mendo's answer at https://stackoverflow.com/a/32137053/5211833
Here is my attempt. You can:
read the function line by line
execute each line, followed by your custom function.
NOTE
This won't work with functions containing for, if, etc..
You can eventually improve the code by passing a function handler with your custom action to runEachLine (and feval with that).
Here a code sample (partly based on this):
foo.m
function foo(args)
a = args{1};
b = 2;
c = a + b;
end
runEachLine.m
function runEachLine( mfile, args )
if nargin < 1
error('No script m-file specified.');
end
if ~strcmp(mfile(end-1:end),'.m')
mfile = [mfile '.m'];
end
if ~exist(mfile,'file')
error(['Cannot access ' mfile])
end
% Read function file
M = textread(mfile,'%s','delimiter','\n');
% Remove empty lines
M = M(~cellfun('isempty',M));
% Input arguments
assignin('base', 'args', args);
% Skipping first line: function [...] = func_name(...)
% Skipping last line : end
for k=2:length(M)-1
try
% Execute each line
evalin('base',M{k})
% Execute your custom function
disp(['Performing Action: ' M{k}]);
catch ME
error('RunFromTo:ScriptError',...
[ME.message '\n\nError in ==> ' mfile ' at ' num2str(k) '\n\t' M{k}]);
end
end
end
Usage:
>>runEachLine('foo.m', {4});
Result:
>> runEachLine('foo.m', {4})
Performing Action: a = args{1};
Performing Action: b = 2;
Performing Action: c = a + b;
>>
No, there is not.
What you present in your original question is just a simple usage of the = operator.
If you want to overload the default behaviour of MATLAB then you should consider creating a class and define the desired behaviour for each operator or function needed.

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