Conditional IF/ELSE Statement in Matlab - matlab

I was trying to make a simple statement with Matlab as follows:
if TF==1
disp('One'), break
else continue
end
... ... ...
... ... ...
But even if TF is not 1, when I run the command, it doesn't CONTINUE to the rest of the script!! Any help would be appreciated-- Thanks

The continue statement has a very different meaning. Within a loop, like a for or while loop, continue instructs to skip the current round and continue with the next iteration in the loop. So if you remove continue, you will see the behavior that you are expecting. Here is an example:
for k = 1 : 10
if k == 4
% skip the calculation in the case where k is 4
continue
end
area = k * k;
disp(area);
end
When the loop iterates at k == 4, the block calculating the area of the corresponding square is skipped. This particular example is not very practical.
However, imagine you have a list of ten file names, and you want to process each file in this loop "for k = 1 : 10". You will have to try and open each file, but then if you find out the file does not exist, an appropriate way to handle it would be to print a little warning and then continue to the next file.

Related

MATLAB : read data file in real time

I have an application, A, that writes to a File.
I want to use MATLAB to read N lines in realtime from this file.
My question is related to this stack post: How to plot real time data from text file in MATLAB
The author of one of the answers, mentions the following approach:
You can't plot using hard real time conditions, thus it can always happen that matlab misses a 10ms timeslot. You have to use option 2 to get all data.
To get started: Write a function which only reads the new data which was written since last call. To achieve this, do not close the file handle. It stores the position.
As such, here is my code:
myfile_fid=fopen(filePath, 'rt')
waitForFileToHaveData(filePath, 10);
for readingIdx = 1:10
fgetl(myfile_fid)
end
My waitForFileToHaveData function, is defined as follows:
function waitForFileToHaveData(filePath, desired_length)
if (getNumLinesOfFile(filePath) < desired_length)
disp('###### not enough data in the file');
pause(0.02);
waitForFileToHaveData(filePath, desired_length);
end
end
function num = getNumLinesOfFile(file_to_read)
[status, result] = system( ['wc -l ', file_to_read] );
if(status~=1)
scanCell = textscan(result,'%u %s');
num = scanCell{1} - 2;
else
num = 0;
end
end
Result:
When I get into the for loop, myfile_fid evaluates to 3, while fgetl(myfile_fid) evaluates to -1. If I print out the results of getNumLinesOfFile(filePath), I see 20. The odd part is that if I wait, say for the file to have 40 lines, and execute the code above, I do not get the error. I tried to look at the documentation to see why fgetl returns back -1, but I cannot seem to find it in 2018b MATLAB documentation. There is mention that the myfile_fid can return a -1, but that is only if the file cannot be opened. However, at runtime, myfile_id evaluates to 3.
Using MATLAB, is it possible to read N number of lines since last read in a file that is being written to by another application?
fgetl returns -1 when fileID reaches the end-of-file marker, See Matlab fgetl documentation. This means that if the first result from fgetl is -1 then the file is empty.
I'm not sure why you are getting -1 if getNumLinesOfFile returns 20, check the code carefully if you are reading the same file. Maybe the file has changed?
I wrote here MATLAB code that checks if 10 new lines were added and and then gets them with fgetl:
myfile_fid = fopen(filePath, 'rt');
newLines = 10;
linesRead = 0;
while(waitForFileToHaveData(filePath, linesRead + newLines))
linesRead = linesRead + newLines;
for readingIdx = 1:newLines
line = fgetl(myfile_fid)
end
end
fclose(myfile_fid);
I updated the waitForFileToHaveData function to return 1:
function ready = waitForFileToHaveData(filePath, desired_length)
while (getNumLinesOfFile(filePath) < desired_length)
disp('###### not enough data in the file');
pause(0.02);
end
ready = 1;
end
Note:
If the file had exactly 10 lines with no end-line marker at line 10, and you read them, then another 10 lines were added, fileID now points to the end-line of line 10 and the first line fgetl will return is the end-line at line 10, but since fgetl removes the end-line, it returns an empty array.
Side note:
the function waitForFileToHaveData uses recursion which is inefficient. You can easily use a while loop.

MATLAB: How to automatically abort failed unit test

I am wondering how I can make a unit test to automatically stop, once an error in the system under test (sut) occurs?
Let's assume, the unit test runs some 1,000 different input combinations, and is supposed to verify that the results are equal to the expectations. Now, let's further assume there is a simple syntax error in sut, which causes an error. In this case I would like the unit test to automatically stop and invoke the tear down method.
Is that possible?
Edit:
I am borrowing a MATLAB example from their help site (https://de.mathworks.com/help/matlab/matlab_prog/create-basic-parameterized-test.html) in order to show more clearly what I mean:
Here you can see the test class:
classdef TestCarpet < matlab.unittest.TestCase
properties (TestParameter)
type = {'single','double','uint16'};
level = struct('small', 2,'medium', 4, 'large', 6);
side = struct('small', 9, 'medium', 81,'large', 729);
end
methods (Test)
function testRemainPixels(testCase, level)
% expected number pixels equal to 1
expPixelCount = 8^level;
% actual number pixels equal to 1
actPixels = find(sierpinski(level));
testCase.verifyNumElements(actPixels,expPixelCount)
end
function testClass(testCase, type, level)
testCase.verifyClass(...
sierpinski(level,type), type)
end
function testDefaultL1Output(testCase)
exp = single([1 1 1; 1 0 1; 1 1 1]);
testCase.verifyEqual(sierpinski(1), exp)
end
end
methods (Test, ParameterCombination='sequential')
function testNumel(testCase, level, side)
import matlab.unittest.constraints.HasElementCount
testCase.verifyThat(sierpinski(level),...
HasElementCount(side^2))
end
end
end
Here's the system under test:
function carpet = sierpinski(nLevels,classname)
if nargin == 1
classname = 'single';
end
% original line: mSize = 3^nLevels;
mSize = "That's clearly wrong here";
carpet = ones(mSize,classname);
cutCarpet(1,1,mSize,nLevels) % begin recursion
function cutCarpet(x,y,s,cL)
if cL
ss = s/3; % define subsize
for lx = 0:2
for ly = 0:2
if lx == 1 && ly == 1
% remove center square
carpet(x+ss:x+2*ss-1,y+ss:y+2*ss-1) = 0;
else
% recurse
cutCarpet(x + lx*ss, y + ly*ss, ss, cL-1)
end
end
end
end
end
end
I changed the definition of mSize to a string to produce an error. Now, if I run the tests, all tests will result in an error. I am wondering if it is possible to stop the tests as soon as possible, i.e. after the occurence of the first error?
The problem that I see is that the test code won't even reach the last line of testRemainPixels (testCase.verifyNumElements(actPixels,expPixelCount)). A fatalAssert does not help at this point, right?
Assuming you are using the test framework built into MATLAB, take a look at the types of qualifications, in particular the bulleted list at the top of this page:
https://www.mathworks.com/help/matlab/matlab_prog/types-of-qualifications.html
If you want to stop the entire testing session you can use fatal assertions. If you want other tests to continue you can use assertions. If you want to skip all the test methods (and parameterizations) in a single file you can use an assertion in TestClassSetup or just add a basic "smoke" level exercise step of the code in TestClassSetup and if it errors it will behave like an assertion.
Hope that helps.

use structure in matlab

I want to use structure in matlab but in first iteration it's run correctly and in other iteration give that message .
1x2 struct array with fields:
my code is :
for i=1:lenfd
currow=rees(i,:)
maxcn=max(currow)
if maxcn~=0
maxin=find(currow==maxcn)
ress(i).x =maxin
end
end
thank you.
That message is not a warning or error. That's just MATLAB printing the output of an operation. And it does that by default, unless you suppress it by appending a semicolon to the command:
for ii = 1:lenfd
currow = rees(ii,:); % <=== NOTE: semicolons at the end
maxcn = max(currow);
if maxcn ~= 0
ress(ii).x = find(currow==maxcn);
end
end
Note that max() may have 2 outputs, the second output being the first index into the array where the maximum occurred. If you know beforehand that any maximum will occur only once, you can skip the call to find() and use the second output of max().

Is there an quivalent to 'jump' or 'go to' in Matlab?

I have this code:
values_nodelay = no_of_values(2:2:end)
no_of_values_x1 = (find(u~=[u(2:end), u(end)+1]));
no_of_values_x1 = no_of_values_x1(2:2:end)
l = 1;
delay = 2;
values_delay = [];
while l<=length(values_nodelay)
values_delay_temp = values_nodelay(l)-delay;
if delay>values_delay_temp
end
values_delay = [values_delay, values_delay_temp];
l = l+1;
end
values_delay
I need a goto or jump function to the beginning of while, or an equivalent if anyone
knows an easier way, that if delay > values_delay_temp, it won't become part of the final vector values_delay. Instead, I want to skip it and continue again with the while loop.
Rather than using jumps like continue or break, you could just do this:
if delay<=values_delay_temp
values_delay=[values_delay, values_delay_temp];
end
In other words make the "default" behavior of the loop to do nothing, and then only increment your vector when you hit the right condition. It's much clearer and easier to debug.
Also instead of using vector concatenation like you have, I've found it's more efficient to do values_delay(end+1) = values_delay_temp; if you have to grow a vector in a loop.
The continue statement will stop the execution of a loop for the current iteration and continue with the next iteration, e.g.
while foo
# stuff that will execute for all iterations
if bar
continue
end
# stuff that won't execute if bar is false
end
Although, in your specific case, why don't you just issue
values_delay=[values_delay, values_delay_temp];
and increase the loop counter when
delay <= values_delay_temp
is true?

'Undefined function or variable' in Matlab

Here is my code:
function [im,sindx,end1]=alln(im,i,j,secret,sindx,end1)
slen=length(secret);
p=im(i,j);
neigh= [im(i-1,j) im(i+1,j) im(i,j-1) im(i,j+1) im(i-1,j-1) im(i+1,j-1) im(i-1,j+1) im(i+1,j+1)];
minpix = min (neigh)
maxpix = max (neigh)
if minpix < p < maxpix
lowlim = minpix+1;
highlim = maxpix-1;
range = highlim-lowlim+1;
nbits=floor(log2(abs(range)));
if sindx+nbits-1>slen
end1=1;
return
end
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
b = bin2dec(bin);
newvalue1 = abs (minpix + b);
newvalue2 = abs (maxpix - b);
if abs(p-newvalue1)<= abs(p-newvalue2)
im(i,j) = newvalue1;
else
im(i,j) = newvalue2;
end
sindx=sindx+nbits;
end
end
My main program calls this function. When I run the program, I get the following error message:
??? Undefined function or variable "bin".
Error in ==> alln at 34
b = bin2dec(bin);
I know there are many experts for whom this is not a problem at all. I am new to MATLAB. Please guys, show me the way, which type of modification in the code can overcome this problem?
First of all, are there some lines missing from the file? Perhaps you've stripped some comments from the top? Because the error message says that
b = bin2dec(bin);
is line 34, but it's line 22 in the code you present.
OK, that aside...
The error message says that 'bin' isn't defined, but I see that it's being set on the line...
bin(k)=secret(sindx+k-1);
That suggests to me that THAT line isn't being run.
I see that that bin = ... line is inside of a 'for' loop, so I suspect that the for loop is run zero times, meaning that 'bin' never gets defined. What is nbits? Is it 1, or perhaps less than 1? THAT would prevent the loop from running at all.
Try removing the semicolon from the end of the
nbits=floor(log2(abs(range)));
line and run your code again.
Leaving off the semicolon will force the value of nbits to be printed in the Command Window. I bet you'll find that it's 1 or less. If that's the case, then start looking at HOW nbits is calculated, and I bet you'll find the problem.
At what input arguments to the function alln, are you getting the error?
Lets suppose that nbits is 0, then the following loop will not run:
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
So, bin will be undefined. So, the error happens. This is one of the cases where the error can happen. There are many such possible cases.