Matlab ask for integer loop - matlab

I'm creating a program to simulate a random walk and it requires the user to input an integer number of steps to take for the walk.
The prompt for this uses code very similar to this:
**% Ask user for a number.
defaultValue = 45;
titleBar = 'Enter a value';
userPrompt = 'Enter the integer';
caUserInput = inputdlg(userPrompt, titleBar, 1,{num2str(defaultValue)});
if isempty(caUserInput),return,end; % Bail out if they clicked Cancel.
% Round to nearest integer in case they entered a floating point number.
integerValue = round(str2double(cell2mat(caUserInput)));
% Check for a valid integer.
if isnan(integerValue)
% They didn't enter a number.
% They clicked Cancel, or entered a character, symbols, or something else not allowed.
integerValue = defaultValue;
message = sprintf('I said it had to be an integer.\nI will use %d and continue.', integerValue);
uiwait(warndlg(message));
end**
However, I want it to simply display the "Enter a value" prompt again if the user does not enter an integer the first time i.e. 4.4.
Any ideas?
Thanks!

if (mod(integerValue,1) == 0)
will evaluate to true if integerValue is an integer. Simply augment your if statement w/ this logic. You might want to consider changing to using a while loop so the user can enter bad input more than once.

The first answer is totally correct for checking for an integer value, but to address the "show prompt again" issue you can just use a loop conditioning it to get the exact kind of data you want:
caUserInput = nan; %or anything worng for that matter
while isempty(caUserInput) || isnan(caUserInput)
caUserInput = inputdlg(userPrompt, titleBar, 1,{num2str(defaultValue)});
end
if you want you can start it again with different argument lines in a more fancy style:
inputiswrong = 1; %or anything worng for that matter
while inputiswrong
inputiswrong = 0;
caUserInput = inputdlg(userPrompt, titleBar, 1,{num2str(defaultValue)});
if isempty(caUserInput )
userPrompt = 'Try again with an input';
inputiswrong = 1;
end
if isnan(caUserInput )
userPrompt = 'not really a number';
inputiswrong = 1;
end
%and so on
end
In both scenarios you should consider transforming the caUserInput to something you could use, i think inputdlg returns a cell so maybe a cell2mat() around the inputdlg().

Remember that unspecified inputs in MATLAB are double-precision by default. For instance a=3 is not an integer. So you should consider two cases:
Integer type
If you are talking about integer type in MATLAB the easiest way is to use isinteger function by MATLAB:
tf = isinteger(A)
for instance:
isinteger(4.4)
=
0
as I mentioned before, 3 is not an integer:
isinteger(3)
=
0
but this one is integer actually:
isinteger(uint8(3))
=
1
To repeat the input query also easily use the same function in a while loop
while ~isinteger(a)
disp('enter an integer');
....
end
Constant double-precision with no decimal
But if you are considering normal constant inputs to be integers you could convert them to integer and compare the result with the original value:
while a ~= double(int64(a))
disp('enter an integer');
....
end
int64 converts the double type to integer, and double converts it back to double. If in this process the number remains unchanged, then you could consider that it was intended to be an integer.
Recommendation for you specific program
I would use a fix function to get rid of the decimal parts. Usually when you receive a double-precision number including decimal values, the main intention is the the number before the floating point. So in many algorithms it is common practice to use fix to round each element of the given number to the nearest integer toward zero.

Related

How to verify that input is numeric in MATLAB

This is the code that I have written to get the corresponsing alphabetic grade for each numerical grade. I want to make sure that the user doesn't enter any strings or characters as input. Only numbers. So I used isnumeric function but the code doesn't work and the while loop doesn't break when I enter a string. It just give me an error. Would appreciate any help. Thank you.
c=input('What is your grade? ');
while 1
if ~isnumeric(c)
break
end
if c>=90 && c<=100
disp('A');
elseif c<90 && c>=80
disp('B');
else
disp('F');
end
end
Have a look at validateattributes. It is much more powerful than a simple isnumeric, e.g. you can specify a range in which the number should lie: {'>',0,'<',10} or ask themt o be nonnegative
validateattributes(x,{'numeric'},{'nonnegative'})
input evaluates what the user enters*. If what the user enters is not a valid MATLAB expression, then you see an error message. Instead,
c = input('What is your grade? ', 's');
The 's' argument makes it so that the function returns exactly what the user typed, as a string. You can then use str2double to convert that to a number. If it's not a number, NaN will be returned. You can test for this:
while true
c = input('What is your grade? ', 's');
c = str2double(c);
if isnan(c)
break
end
disp(c)
end
* This evaluation actually makes input dangerous to use in this form, for example the user can enter delete('c:/windows') or something like that to destroy your system.

Numerical values associated with Drop Down options

So I am creating an app to work out a value based on a series of variables. The variables are:
Gender
Age
Weight
Creatinine
Here's what the app looks like:
In order to simplify the process somewhat I decided to make the gender selection a dropdown menu, this has caused me some issues since I have it setup like so:
And the maths associated with the button looks like so:
function CalculateButtonPushed(app, event)
gender = app.PatientGenderDropDown.Value ;
age = app.PatientAgeEditField.Value ;
weight = app.LeanBodyWeightEditField.Value ;
serum = app.SerumCreatinineEditField.Value ;
final = (gender*(age)*weight) / (serum) ;
app.ResultEditField.Value = final ;
end
end
Running this gives the following error:
Error using
matlab.ui.control.internal.model.AbstractNumericComponent/set.Value
(line 104) 'Value' must be numeric, such as 10.
As far as I am aware, the values I input into ItemsData are numeric values. Have I missed something or is there a better way to do this?
If you put a breakpoint in the offending file on the appropriate line (by running the below code),
dbstop in uicomponents\+matlab\+ui\+control\+internal\+model\AbstractNumericComponent.m at 87
you could see the following in your workspace, after clicking the button:
There are two separate problems here, both of which can be identified by looking at the newValue validation code (appearing in AbstractNumericComponent.m):
% newValue should be a numeric value.
% NaN, Inf, empty are not accepted
validateattributes(...
newValue, ...
{'numeric'}, ...
{'scalar', 'real', 'nonempty'} ...
);
Here are the issues:
The new value is a vector of NaN.
The reason for this is in this line:
final = (gender*(age)*weight) / (serum) ;
where serum has a value of 0 - so this is the first thing you should take care of.
The new value is a vector of NaN.
This is a separate problem, since the set.Value function (which is implicitly called when you assign something into the Value field), is expecting a scalar. This happens because gender is a 1x4 char array - so it's treated as 4 separate numbers (i.e. the assumption about ItemsData being a numeric is incorrect). The simplest solution in this case would be to str2double it before use. Alternatively, store the data in another location
(such as a private attribute of the figure), making sure it's numeric.

Scientific notation in MATLAB

Say I have an array that contains the following elements:
1.0e+14 *
1.3325 1.6485 2.0402 1.0485 1.2027 2.0615 1.7432 1.9709 1.4807 0.9012
Now, is there a way to grab 1.0e+14 * (base and exponent) individually?
If I do arr(10), then this will return 9.0120e+13 instead of 0.9012e+14.
Assuming the question is to grab any elements in the array with coefficient less than one. Is there a way to obtain 1.0e+14, so that I could just do arr(i) < 1.0e+14?
I assume you want string output.
Let a denote the input numeric array. You can do it this way, if you don't mind using evalc (a variant of eval, which is considered bad practice):
s = evalc('disp(a)');
s = regexp(s, '[\de+-\.]+', 'match');
This produces a cell array with the desired strings.
Example:
>> a = [1.2e-5 3.4e-6]
a =
1.0e-04 *
0.1200 0.0340
>> s = evalc('disp(a)');
>> s = regexp(s, '[\de+-\.]+', 'match')
s =
'1.0e-04' '0.1200' '0.0340'
Here is the original answer from Alain.
Basic math can tell you that:
floor(log10(N))
The log base 10 of a number tells you approximately how many digits before the decimal are in that number.
For instance, 99987123459823754 is 9.998E+016
log10(99987123459823754) is 16.9999441, the floor of which is 16 - which can basically tell you "the exponent in scientific notation is 16, very close to being 17".
Now you have the exponent of the scientific notation. This should allow you to get to whatever your goal is ;-).
And depending on what you want to do with your exponent and the number, you could also define your own method. An example is described in this thread.

how to make matlab detect incompatible type assignments?

hi have a major problem in matlab. I have a function and it sometimes returns control ascii characters. How do i check for the presence of these control ascii ?.
my code looks like this
d = out.autoc
d sometimes receives control ascii characters instead of a actual double value. Does someone know how to catch such incompatible assignments ?
I think this should work but you may want to double check the ASCII codes to exclude.
%here I load Ctrl-C
s = sprintf('%s', 3);
code = bin2dec(dec2bin(s,8));
if code < 32
fprintf('ignore');
else
fprintf('do somsething');
end
If you want to check that the value of d is double, and not a string. You can check it this way:
if ~isnumeric(d) || ~isdouble(d)
fprintf('d is not of class double\n');
end
But if you want to assign the value of out.autoc to d only if out.autoc is double, you can do this:
if isnumeric(out.autoc) && isequal(class(out.autoc), 'double')
d = out.autoc;
else
fprintf('out.autoc is not of class double, no assignment made.\n');
end

format a number as I want

I have the number: a = 3.860575156847749e+003; and I would show it in a normal manner. So I write b = sprintf('%0.1f' a);. If I print b I will get: 3860.6. This is perfect. Matter of fact, while a is a double type, b has been converted in char.
What can I do to proper format that number and still have a number as final result?
Best regards
Well, you have to distinguish between both the numerical value (the number stored in your computer's memory) and its decimal representation (the string/char array you see on your screen). You can't really impose a format on a number: a number has a value which can be represented as a string in different ways (e.g. 1234 = 1.234e3 = 12.34e2 = 0.1234e4 = ...).
If you want to store a number with less precision, you can use round, floor, ceil to calculate a number which has less precision than the original number.
E.g. if you have a = 3.860575156847749e+003 and you want a number that only has 5 significant digits, you can do so by using round:
a = 3.860575156847749e+003;
p = 0.1; % absolute precision you want
b = p .* round(a./p)
This will yield a variable b = 3.8606e3 which can be represented in different ways, but should contain zeros (in practice: very small values are sometimes unavoidable) after the fifth digit. I think that is what you actually want, but remember that for a computer this number is equal to 3.86060000 as well (it is just another string representation of the same value), so I want to stress again that the decimal representation is not set by rounding the number but by (implicitly) calling a function that converts the double to a string, which happens either by sprintf, disp or possibly some other functions.
Result of sprintf y a text variable. have you tried to declare a variable as integer (for example) and use this as return value for sprintf instruction?
This can be useful to you: http://blogs.mathworks.com/loren/2006/12/27/displaying-numbers-in-matlab/