Here is my code:
friendly_output = num2str(std(counts_channel),'%.4f');
if friendly_output > 0 && friendly_output <= 1000
variable = 100
elseif friendly_output > 1000 && friendly_output <= 1500
variable = 500
The variable friendly_output here is a decimal number. However, while I am executing this code, this prompts me the error:
Operands to the || and && operators must be convertible to logical
scalar values
I tried to solve the issue by replacing && with &, the program works, but the variable friendly_output failed to catch the correct if statement.
I tried to output the value of friendly_output, the value is correct but the statement it goes into is wrong.
Thank you.
If my guess is correct, your friendly_output is of type char
To check that, try this:
class(friendly_output)
If you need to compare it with an integer, you need to convert it back to a number.
To do this add this code after the first line
friendly_output = str2double(friendly_output);
%// changed from `eval` to `str2double` as suggested by #horchler
%// Using `str2double` over `eval` or `str2num` is a best practice.
%// or you could just avoid `num2str` conversion
PS:
The && operator didn't work for you because they work good only on scalar inputs. But as the friendly_output variable is a char array, you got the error.
While & works on array inputs, Each char is first converted to its corresponding ASCII value and then compared with the number. So even though Matlab doesn't post an error, the results won't be favorable to you.
For more information on the difference between & and && Refer Here
Here is an example of what is happening when you don't convert the string back to number:
>> a = '1200.5'
a =
1200.5
>> a > 1000
ans =
0 0 0 0 0 0
The ASCII values of char 0-9 ranges from 49-57 while ASCII value of char '.' is 46
Although, 1200.5 is greater than 1000, it actually calculate this way
50(char '1') is not greater than 1000.
51(char '2') is not greater than 1000.
49(char '0') is not greater than 1000.
49(char '0') is not greater than 1000.
46(char '.') is not greater than 1000.
54(char '5') is not greater than 1000.
Related
I'm creating a function in MatLab that prompts for user input and then displays a message depending on that input. A valid input (an integer from 1-10) will show a message of 'Input recorded' (this is working), and any other input (ie. non integer values, integers outside the range, or text) should display 'Invalid input, try again', and then prompt the user for an input again.
This is the function as it stands:
n = 0;
while n == 0
userInput = input('Input an integer from 1 - 10\n');
switch userInput
case {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
disp('Input recorded');
n = 1;
otherwise
disp('Invalid input, try again')
pause(2);
n = 0;
end
end
At the moment, an integer input within the range triggers the confirmation message and breaks out of the while loop, and any other numeric input triggers my 'Invalid input' message and cycles round again, however, a text input (eg "five") gives me a MatLab error message (image of my console window output included). How do I let the switch statement also accept a text input, to avoid breaking my code if the user types text?
Obviously I'm using a switch for this at the moment, but I'm sure there might be a better solution with an if, elseif statement - I'm open to any solution that gets the job done!
If you use input with just one parameter, MATLAB tries to evaluate any expression in the input. So if someone gives an input like e.g. 'a', MATLAB will search for 'a' in the variables of your current workspace. Since there's no defined variable with that name, MATLAB will throw an exception.
That's why you have to specify the format in input as second parameter. I'd suggest you to define the specify the format string, then the input can be anything. Then convert the string to a double number and start checking the input:
n = 0;
while n == 0
userInput = input('Input an integer from 1 - 10\n','s'); %Read input and return it as MATLAB string
userInput = str2double(userInput);
if (~isnan(userInput) && ... %Conversion didn't fail AND
mod(userInput,1) == 0 &&... %Input is an integer AND
userInput >= 1 && userInput <= 10) %Input is between 1 AND 10
disp('Input recorded');
n = 1;
else
disp('Invalid input, try again')
pause(2);
n = 0;
end
end
I have been trying to execute a piece of code with some if conditions. This is a simple version of it.
X=100;Y=100;
if ((((X+1) && (Y+1))<=99) && (((X+1) && (Y+1))<=102))
disp(X);
end
Despite both X and Y not satisfying the first condition, I still get the output as 100. I have tried all combinations of & and && to make the and operations in the work. I checked the difference between the two and I found that & is a logical bit-wise operator while && is a short-circuit operator, which probably doesn't change much in this context. What's the error with this syntax?
Of course the code works when I do this:
X=100;Y=100;
if (X+1)<=99 && (Y+1)<=99 && (((X+1) && (Y+1))<=102)
disp(X);
end
But this is so inefficient when there are lot of conditions and each sub-condition must include the constraints. I'm sure this must be answered somewhere and this question might be a duplicate, so please point me to the answer.
So it looks like you understand what (X+1)<=99 && (Y+1)<=99 does. Let's look at ((X+1) && (Y+1))<=99:
&& requires a logical value on each side. a && b will turn a and b into logicals, effectively becoming a~=0 && b~=0. Thus:
((X+1) && (Y+1) ) <= 99
((X+1)~=0 && (Y+1)~=0) <= 99
( true && true ) <= 99
1 <= 99
true
Of course the truth value of (X+1)~=0 and (Y+1)~=0 could be different, but here you see this. In MATLAB, true is equal to 1 in a non-logical context, as when compared to 99.
If you want to simplify this expression, use max instead of &&:
X=100;Y=100;
if max(X+1,Y+1)<=99 && max(X+1,Y+1)<=102
disp(X);
end
If the max of a and b is smaller than 99, then both a and b are smaller than 99.
(Obviously, the statement can be further simplified to if max(X+1,Y+1)<=102, since if the second inequality holds than so must the first.)
I want to check the length of string got more than 20 characters, if more than 20 then will return 1 else return 0 in matrix form [n x 1]. But now, I get the answer of [1x1]. How do I modify my code in if-else statement to get the ans?
str = {'http://www.mathworks.com/matlabcentral/newsreader/view_thread/324182',
'http://jitkomut.lecturer.eng.chula.ac.th/matlab/text.html',
'http://www.ee.ic.ac.uk/pcheung/teaching/ee2_signals/Introduction%20to%20Matlab2.pdf'};
a = cellfun(#length,str)
if a > 20
'1'
else
'0'
end
Output:
a =
68
57
83
ans =
1
I want the output of, lets say
ans =
1
1
1
In Matlab, you can simply use (no if statement is needed):
a = cellfun(#length,str)
(a>20)'
This will give you:
a =
68 57 83
ans =
1
1
1
As #herohuyongtao mentions, you don't actually need an if, the if will only consider the first element of the matrix that it returns, hence giving you only a single value.
But you could actually do this all in your cellfun by using an anonymous function:
cellfun(#(x)(length(x) > 20), str)
And get the result in one shot.
As there is no equivalent of the c ternary operator (?:) in matlab, you can use the following two statements to replace your if then else statement, and achieve what you ask for:
b(a==a)='0'
b(a>20)='1'
The first line initializes the result array, where all value b defaults to the value of the else branch, i.e. '0',
the second line changes the elements for which the conditional > 20 holds to the value in the then branch, i.e. '1'.
If the output values are boolean, you can simply do:
(a>20)
as #herohuyongtao suggested or use #Dan's answer.
I have a very trivial example where I'm trying to filter by matching a String:
A = [0:1:999];
B = A(int2str(A) == '999');
This
A(A > 990);
works
This
int2str(5) == '5'
also works
I just can't figure out why I cannot put the two together. I get an error about nonconformant arguments.
int2str(A) produces a very long char array (of size 1 x 4996) containing the string representations of all those numbers (including spacing) appended together end to end.
int2str(A) == '999'
So, in the statement above, you're trying to compare a matrix of size 1 x 4996 with another of size 1 x 3. This, of course, fails as the two either need to be of the same size, or at least one needs to be a scalar, in which case scalar expansion rules apply.
A(A > 990);
The above works because of logical indexing rules, the result will be the elements from the indices of A for which that condition holds true.
int2str(5) == '5'
This only works because the result of the int2str call is a 1 x 1 matrix ('5') and you're comparing it to another matrix of the same size. Try int2str(555) == '55' and it'll fail with the same error as above.
I'm not sure what result you expected from the original statements, but maybe you're looking for this:
A = [0:1:999];
B = int2str(A(A == 999)) % outputs '999'
I am not sure that the int2str() conversion is what you are looking for. (Also, why do you need to convert numbers to strings and then carry out a char comparison?)
Suppose you have a simpler case:
A = 1:3;
strA = int2str(A)
strA =
1 2 3
Note that this is a 1x7 char array. Thus, comparing it against a scalar char:
strA == '2'
ans =
0 0 0 1 0 0 0
Now, you might wanna transpose A and carry out the comparison:
int2str(A')=='2'
ans =
0
1
0
however, this approach will not work if the number of digits of each number is not the same because lower numbers will be padded with spaces (try creating A = 1:10 and comparing against '2').
Then, create a cell array of string without whitespaces and use strcmp():
csA = arrayfun(#int2str,A','un',0)
csA =
'1'
'2'
'3'
strcmp('2',csA)
Should be much faster, and correct to turn the string into a number, than the other way around. Try
B = A(A == str2double ('999'));
I've been learning matlab for the past week as my job requires it, but I'm kinda stuck. I want to create a function that removes all data points within lowerBound and upperBound. What's wrong with this code?
mask = ~((data.HB_X > lowerBound) && (data.HB_X < upperBound));
data.HB_X = data.HB_X(mask);
data.HB_Y = data.HB_Y(mask);
The error is
??? Operands to the || and && operators must be convertible to logical scalar values.
Error in ==> myGUI>deleteHBs at 228
mask = ~((data.HB_X > lowerBound) && (data.HB_X < upperBound));
The problem is exactly what the error message says. You can only use the shortcut operators && and || for scalar comparisons. If you compare arrays, you need to use & and |, respectively.