Numeric Data Validation While Loop in Matlab - matlab

I have a function usenum
function TF = usenum(x)
TF = false;
if ~isnumeric(x)
h = msgbox('Input is not numeric');
elseif (x <= 0)
h = msgbox('Input must be > 0');
else
TF = true;
end
I am getting user input in the main menu:
answer = inputdlg(prompt,dlg_title,num_lines,def);
The inputdlg has 2 values and can be indexed by {1} and {2}
I want to wait for the user to input a value, the value has to be a number and greater than 0. in the case that he doesn't, I want to output the respective message and make him keep inputting until he gets it right, or close the inputdlg dialog.
I am attempting something like this:
condition = false;
while ~condition
answer = inputdlg(prompt,dlg_title,num_lines,def);
numOfTracks = answer{1};
bpmRange = answer{2};
condition = usenum(numOfTracks);
end
I am trying to say, while condition = false, i.e. while input is not numeric or not greater than 0, keep getting user input. Once the user inputs a valid number the condition is supposed to become true and the while is supposed to terminate. However, the inputdlg keeps opening for input and the only way I can stop it is by closing it (infinite loop). how can I achieve what I want?
Thanks in advance

Your loop appears to be correct. The following testing provides results of your usenum function.
>> usenum('')
ans =
0
>> usenum(-1)
ans =
0
>> usenum(1)
ans =
1
Your usenum function is correct as far as typing is concerned, but I believe your input is always given as a string since you're getting user input from a dialogue. Instead, you should try redefine usenum as follows if you're expecting a string input. The function str2double converts it to a double and if it's text, it will show as NaN. That's what the isnan check is for, to check if it's text.
function TF = usenum(x)
% Default to false
TF = false;
x = str2double(x);
% Check if digits
if isnan( x )
h = msgbox('Input is not numeric');
elseif (x <= 0)
h = msgbox('Input must be > 0');
else
TF = true;
end
This is the result of the new function.
>> usenum('a')
ans =
0
>> usenum('-1')
ans =
0
>> usenum('1')
ans =
1

Related

MATLAB: Trying to not display the logical array in this code

This is a function that checks if the array that is inputted is a square matrix. The function is doing what I want, namely checking if the array is square, but it also outputs the logical array that I am using to check if the number of rows equals the number of columns.
function isSquare = checkSquare(x)
[rnum, cnum] = size(x);
isSquare = rnum == cnum;
if isSquare == 1
fprintf('True')
else
fprintf('False')
end
end
I think it's because you're running the function without putting a semicolon at the end.
>> checksquare(zeros(4,4))
True
ans =
logical
1
>>
Instead, try this.
>> checksquare(zeros(4,4));
True>>
It would be nicer for the formatting to print a newline character after True or False. Change fprintf('True') to fprintf('True\n') and fprintf('False') to fprintf('False\n') and you'll get the following result.
>> checksquare(zeros(4,4));
True
>>

Error of declaration of variable

I have a problem at the beginning of my function. The function is to combine several data column from some objects. Error happens at the beginning of function. It says as follows:
Error in find_by_coor (line 2)
for i = 1:length(obj_ac)
Here is only the declaration of variable and loop, but Matlab somehow returned error. I have no idea so would like someone to help me. I attached my code as follows. Thanks a lot in advance.
function arr = find_by_coor(obj_ac,obj_gps,obj_sen_dir,lat1,long1,lat2,long2)
for i = 1:length(obj_ac)
if eq(obj_sen_dir(i).sensor,4) && strcmp(obj_sen_dir(i).direction,'outbound')
ind = obj_gps(i).save_var_gps(:,1)>lat1;
if isempty(find(ind)) == 1
continue
end
temp = obj_gps(i).save_var_gps(ind,:);
ind = temp(:,1)<lat2;
if isempty(find(ind)) == 1
continue
end
temp2 = temp(ind,:);
ind = temp2(:,2)<long1;
if isempty(find(ind)) == 1
continue
end
temp3 = temp2(ind,:);
ind = temp3(:,2)>long2;
if isempty(find(ind)) == 1
continue
end
temp4 = temp3(ind,:);
mint = min(temp4(:,5))-min(obj_gps(i).save_var_gps(:,5));
maxt = max(temp4(:,5))-min(obj_gps(i).save_var_gps(:,5));
if isempty(mint) == 1 || isempty(maxt) == 1
continue
end
if floor(mint*(1.6516e+03)) == 0 || floor(maxt*(1.6516e+03)) == 0
continue
end
temp5 = obj_ac(i).save_var(floor(mint*(1.6516e+03)):floor(maxt*(1.6516e+03)));
temp6 = abs(fft(temp5));
arr(i,:) = [i objs(i).daten var(temp5) max(temp5) min(temp5) mean(temp5) std(temp5) mode(temp5) var(temp6) max(temp6) min(temp6) mean(temp6) std(temp6) mode(temp6)];
disp(i);
end
end
end
The problem is that when you run the function, the output variable arr is never assigned. In Matlab you must always assign a function output if you choose to have it in the definition. For example
function [a,b] = setAB()
err = 0; % Gives an error if err is true
a = 1;
if ~err
b = 1;
end
The reason is most certainly that for some inputs, all values fall into one of the if statements and you do never reach the point where arr is assigned. A good solution for this is to assign a default value for arr in the beginning. That may for example be nan or -1 or, in your case maybe an array arr = nan(wanted size) or arr = -1*ones(wanted size). If you do not preallocate arr you will likely get a "matrix out of bounds" error instead, should you solve the first issue.
It does not mean that you always need to have an output though.
function [] = noOutput()
disp('Hi, I am a void!');
You may also choose to return as many values as number of outputs.
function varargout = variableArgs()
a = 1;
b = 2;
c = 3;
if (nargout == 1)
varargout{1} = a;
elseif (nargout == 2)
varargout{1} = b;
varargout{2} = c;
else
error('Wrong number of output arguments!');
end
I am not saying which of the approaches you should use or that any of them are good. Normally I use varargout in case I write plotting functions. Then I may want to return nothing in case I do not have an output argument. Then I want to return handles or any extra information. Further as you may have understood there is also a varargin that may be of more use.

how to control return variable in matlab

i want to clarify how to control returning of variables from function in matlab,for exmaple let us consider this code
function [x y z]=percentage(a)
n=length(a);
maximum=0;
minimum=0;
subst=0;
minus=0;
plus=0;
minus_perc=0;
plus_perc=0;
for i=1:1:n
if a(i)>0
plus=plus+1;
else
minus=minus+1;
end
end
minuc_perc=minus/n;
plus_perc=plus/n;
maximum=max(minus_perc,plus_perc);
minimum=min(minus_perc,plus_perc);
subst=maximum-minimum;
x=plus_perc;
y=minus_perc;
z=subst*100;
if plus_perc>minus_perc
disp('among the successful people,relevant propession was choosen by');
disp(z)
disp('% people');
else
disp('among the successful people,irrelevant propession was choosen by');
disp(z);
disp('% people');
end
end
what i want to return is plus_proc,min_proc and subst,but when i run following command,get result like this
[c d e]=percentage(a)
among the successful people,relevant propession was choosen by
58.3333
% people
c =
0.5833
d =
0
e =
58.3333
so i think something is wrong,array is like this
a =
1 -1 1 1 -1 1 -1 -1 1 1 1 -1
so ones again,i want to return plus_proc,minus_proc,and subst
To return a variable in matlab you just assign into one of the specified return parameters. For example: to return the number five I would use:
function [foo] = gimmeFive()
foo = 5;
end
Your code is not giving you the right answer because you have a typo:
minuc_perc=minus/n;
should be
minus_perc=minus/n;
You could greatly simplify the function by taking advantage of the find function, like so:
Find the indeces of any element of a > 0, count them.
plus = length(find(a > 0));
plus_perc = plus ./ length(a);
Or if you want to cut even more out:
a > 0 gives us a vector of 0 and 1, so sum up the 1's
plus = sum(a > 0);
plus_perc = plus ./ length(a);

Matlab function return value

I have one program that has function and the problem, return value, it has too many output.
Like exempley: y = text the answer comes up
Error in text (line 2)
if nargin == 0
Output argument "array" (and maybe others) not assigned during call to "
C:\Users\name\Documents\MATLAB\text.m>text".
The program text.m reads a txt file that contains a couple of names and numbers like
exemple:
John doughlas 15986
Filip duch 357852
and so on. The program convert them to 15986 Doughlas John and so on.
function array = text(~)
if nargin == 0
dirr = '.';
end
answer = dir(dirr);
k=1;
while k <= length(answer)
if answer(k).isdir
answer(k)=[];
else
filename{k}=answer(k).name;
k=k+1;
end
end
chose=menu( 'choose file',filename);
namn = char(filename(chose));
fid = fopen(namn, 'r');
R = textscan(fid,'%s %s %s');
x=-1;
k=0;
while x <= 24
x = k + 1;
All = [R{3}{x},' ',R{1}{x},' ',R{2}{x}];
disp(All)
k = k + 1;
end
fclose(fid);
Is there anyway to fix the problem without starting over from scratch?
Grateful for all the answers!
You specify the function output argument in the definition, but you don't assign anything to it in the function body.
For example, in
function y = student(j)
your output is y. So you have to assign something to y.
Read more about functions in MATLAB.
Here is a working example.
The first part is to create a function called 'functionA' in a filename 'functionA.m'. Then put the following code inside:
function result = functionA(N,alpha)
result = 5;
return
end
The second part is to create another Matlab file(i.e. upto you to name it) or you can use the Matlab command window even. Then run the following code:
getresult = functionA(100,10);
getresult
After running you get the following answer:
ans =
5

Need help on clarification of input dialog of matlab

Suppose I have the following code:
%%input dialog box%%%
prompt = {'Enter gain:','Enter range:'};
dlg_title = 'Enter values';
num_lines= 1;
def = {'20','256'}; %default
answer = inputdlg(prompt,dlg_title,num_lines,def);
%%%to get the two entered values%%%%
A = getfield(answer,{1}); %first input field
A = str2double(A);
B = getfield(answer,{2}); %second input field
B = str2double(B);
What does it mean to use "dynamic field names with structures instead of getfield"?
How can I use a loop for the input values that are complex and smaller than zero, in the sense to request the user for another compatible input?
I've tried the following loop but it does not work. Why?
while isnan(A) || ~isreal(A) || A<0
prompt = {'Enter gain:'%'Enter range:'};
dlg_title = {'undefine!!'};
num_lines= 1;
def = {'',''}%{'20','256'}; %default
answer = inputdlg(prompt, dlg_title, num_lines, def);
A = getfield(answer,{1}); %first input field
A = str2double(A);
%A = str2double(input('Enter the value of module(mm) : ', 's'));
end
The calls to getfield aren't required and frankly don't make any sense. The variable answer is a cell array not a struct so you don't need to use getfield The second half of the pasted code could be replaced with:
A = str2double( answer{1} );
B = str2dobule( answer{2} );
With regards to looping until you get valid input. You can use a boolean flag, a while, loop and a function (lets call it areInputsValid()) that returns true if the inputs are valid
validInput = false;
while (~validInput)
% input dialog box
% code here
% get the two entered values
& code here
validInput = areInputsValid(A, B);
end