special compare in MATLAB - matlab

Hi I'm trying to achieve this:
for i=1:maxaps
for j=1:length(num2)
**if (isequal(sortedCell(i),txt2(j)) && sortedCell(i)~=0)** %important line
rssi2sorted(i)=rssi2(j); %I don't think we need matching part
break;
end
end
end
and I receive this error:
??? Undefined function or method 'ne'
for input arguments of type 'cell'.
Error in ==> sortingmethod at 116
if
(isequal(sortedCell(i),txt2(j))
&& sortedCell(i)~=0)
if I try like this:
for i=1:maxaps
for j=1:length(num2)
**if (isequal(sortedCell{i},txt2(j)) && sortedCell(i)~=0)** %important line
rssi2sorted(i)=rssi2(j); %I don't think we need matching part
break;
end
end
end
the elements can't be compared because of the format:
>> sortedCell{1}
ans =
00:1e:58:f4:15:f7
>> txt2(6)
ans =
'00:1e:58:f4:15:f7'
any recommendations on how to fix this?
Thanks!

I believe that the issue is actually with this part (the ne that your error refers to):
sortedCell(i)~=0
You're comparing a cell, rather than its contents, to zero. You should use:
sortedCell{i}~=0
EDIT:
If the question is not about the error message, but rather how to compare strings, just use strcmp (never use ==, eq, or isequal to compare strings):
if strcmp(sortedCell{i},txt2(j))
...
end
I don't know what the && sortedCell{i}~=0 part you've added is for, but you can add it back if needed.
strcmp also take cell arrays as inputs (see the documentation) so you may be able to get rid of on of your for loops. I don't know what your code does, but maybe you you could use something like this:
for j=1:length(num2)
c = strcmp(sortedCell,txt2(j));
if any(c)
rssi2sorted(c)=rssi2(j);
break;
end
end

use strcmp (of strcmpi ignoring case) to test is strings are the same, isequal is for testing if values are numerically equal. e.g.
if ( strcmp(sortedCell{i},txt2(j)) && sortedCell(i)~=0 )

Related

Comparing Multiple File Types in an if Statement

I am importing a file into a function using [filepath, name, ext]=fileparts(thisFile);. I would then like to use a series of if statements that will operate on the file depending on its type; however, come files will have the same initial set up and so I would like to be able to include them all in an if statement. My current implementation: elseif (ext == '.s3p'). If I put in something like: elseif (ext == '.s2p' || '.s3p') the compiler whines,
Operands to the || and && operators must be convertible to logical scalar values.
You see my logic. Is there anything that I can do to make this work?
Thank you in advance!
You probably want strcmp, not ==. With a==b you get element-wise comparison. So you get a logical vector as result; and if a and b have different number of characters you get an error.
The fact that the output of == is a logical vector of element-wise comparisons is what causes the m-lint message. || and && require scalar arguments.
Lastly, in (ext == '.s2p' || '.s3p') you probably meant (ext == '.s2p' || ext == '.s3p').
Combining all of the above:
elseif strcmp(ext,'.s2p') || strcmp(ext,'.s3p')
For clarity and readability, you may prefer to use the ismember function with a cell array of the extensions to compare with:
elseif ismember(ext, {'.s2p' ,'.s3p'})
or, as pointed out by Cris Luengo,
elseif any(strcmp(ext, {'.s2p', '.s3p'}))
Better yet, instead of a series of elseif statements you may prefer to use switch, which implicitly applies strcmp / ismember for each case:
switch ext
case {'sp2', 'sp3'}
% Do stuff
case {'aaa', 'bbb'}
% Do stuff
otherwise
error('Unrecognized extension')
end

Output of Matlab function is an empty array

I have a Matlab function which returns an array with probability alpha and nothing (i.e. an empty array) with probability 1-alpha:
function [binary_array_e1 , binary_array_e2 ] = croiser(binary_array_p1,binary_array_p2,alpha )
binary_array_e1=[];
binary_array_e2=[];
compt=1;
if (rand <= alpha)
% some stuff that will put sth in binary_array_e1 and binary_array_e2
end
My question is: how should I manage the fact that the function could return empty arrays at the call of the function? Is something like:
[binary_array_e1 , binary_array_e2]=croiser(binary_array_p1,binary_array_p2,alpha);
be sufficient?
If you want to return an empty variable from a function call, you are totally allowed to do it and you are on the right path. Initialize your variables as empty at the beginning of the function...
function [binary_array_e1 , binary_array_e2 ] = croiser(binary_array_p1,binary_array_p2,alpha )
binary_array_e1=[];
binary_array_e2=[];
% ...
end
and then just check the outcome whenever you need to do it, for example:
[binary_array_e1,binary_array_e2] = croiser(binary_array_p1,binary_array_p2,alpha);
if (isempty(binary_array_e1))
% do something 1...
elseif (isempty(binary_array_e2))
% do something 2...
else
% do something 3...
end
Of course, in order to check the outcome, both variables must be returned and evaluated. But if you are returning two empty arrays in one case and two non-empty arrays in the other case, you could also check only one array:
if (isempty(binary_array_e1))
% do something...
else
% do something else...
end
Anyway... there are so many ways to obtain the same result. For example, you could also return a 'logical' variable that tells you immediately if your arrays have been filled with something or not, or you could return a 'struct' filled with your data in order to make everything more compact (I can elaborate on these solutions if you want). It's up to you but I see nothing wrong in your approach!
Yes, that should be fine. You can later check if the output is an empty array using the function isempty

If and elseif, only the first line work?

L=1; Nx=51; PeriodicFlag=1; T=15; Nt=51;
spacedef='Pade6FirstDeriv'; casedef='LinearAdvection';
if (spacedef == 'Pade6FirstDeriv')
D1 = sparse(Pade6(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Upwind3FirstDeriv')
D1 = sparse(Upwind3(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Central4FirstDeriv')
D1 = sparse(Central4(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Central2FirstDeriv')
D1 = sparse(Central2(Nx,dx,PeriodicFlag));
else
error(sprintf('Unknown spacedef = %s',spacedef));
end
In the above code, the if section is a small segment from a function I've constructed. I'm trying to get the function to know which methods to use based on my input (spacedef). Central2, Central4, Upwind3, and Pade6 are other functions I've written. The weird thing is that when spacedef =/= to 'Pade6FirstDeriv', I would get an error stating Error using ==, Matrix dimensions must agree. I've tried swapping the order of the if loop (by placing Central4, Central2, Pade6, and Upwind3 in the first line of the loop), and it seems like only the top line of the loop will work (the elseifs are not working). I'd greatly appreciate it if anybody can help me out. Thanks!
As has been noted in the comments, this is a common error when people first start comparing strings in MATLAB, and strcmp or strcmpi is generally the solution.
However, one solution the questions links in the comments don't present, and a solution I think looks much nicer, is the switch statement:
switch (spacedef)
case('Pade6FirstDeriv')
D1 = sparse(Pade6(Nx,dx,PeriodicFlag));
case('Upwind3FirstDeriv')
D1 = sparse(Upwind3(Nx,dx,PeriodicFlag));
case('Central4FirstDeriv')
D1 = sparse(Central4(Nx,dx,PeriodicFlag));
case('Central2FirstDeriv')
D1 = sparse(Central2(Nx,dx,PeriodicFlag));
otherwise
error(sprintf('Unknown spacedef = %s',spacedef));
end
Note: if I expect others to use my code with string comparisons, I usually lower the input such that the comparison is case-insensitive, although I have not done that here.

matlab - what is the equivalent of null / None / nil / NULL etc.?

In most OO languages, where variables may point to objects, they may also have a null value, which is highly convenient.
In Matlab, I have a function which parses a command, and then returns a cell array, or false (which is equal to zero — which is another common pattern) if it fails:
function re = parse(s)
...
if (invalid)
re = false;
return;
end
end
The problem is that when I check the result, it gives an error:
re = parse(s);
if (false == re)
Undefined function 'eq' for input arguments of type 'cell'.
I've written a function to check it without an error: strcmp('logical', class(re)) && false == re, but that seems to be really slow for use in hot areas of the code, and also inconvenient if I have to add this function to every M file I'm writing.
Using NaN is even worse, because besides throwing that error, it also isn't equal to itself.
What's a better alternative for use with this pattern?
You can use the isequal function to compare any two items without causing that error. For example:
if isequal (re, false)
%code here
end
A good alternative is to use the empty array: [] and isempty(re) to check. This doesn't throw the error.
Reference: http://www.mathworks.com.au/matlabcentral/newsreader/view_thread/148764
If you can change the function parse one solution would be to return two output arguments [re status] = parse(s), where status would be logical variable. Set it to true in case of success, and to false otherwise.
I would use the empty cell array {} if it is not a valid result otherwise. Using empty matrices is MATLAB standard (see Evgeni Sergeev's answer), but using an empty cell array instead of an empty numeric array ensures that you'll always end up with the same type of result.
If, on the other hand, the empty cell array {} is a valid result of your function, then I'd use an exception to signalize a problem:
if invalid
error('Parse:InvalidArgumentError', 'The input is invalid.');
end
Make sure to use an appropriate error ID (first argument to error) so that you can catch exactly that exception when you call the function:
try:
result = parse(something);
catch ME
if strcmp(ME.identifier, 'Parse:InvalidArgumentError')
fprintf('Ooops\n');
else
% Some other error
ME.rethrow();
end
end
I think the problem is that matlab functions don't return pointers but copies of values.
IMHO the best best approach would be to define your own "pointer" class. Inside you can define an "isNull()" command or even override comparison to produce the behavior you desire.

MATLAB console output

Say I had a variable called "x" and x=5.
I would like to do:
disp('x is equal to ' + x +'.');
and have that code print:
x is equal to 5.
This is how I am used to doing things in Java, so their must be a similar way to do this in MATLAB.
Thanks
If you want to use disp, you can construct the string to display like so:
disp(['x is equal to ',num2str(x),'.'])
I personally prefer to use fprintf, which would use the following syntax (and gives me some control over formatting of the value of x)
fprintf('x is equal to %6.2f.\n',x);
You can, of course, also supply x as string, and get the same output as disp (give or take a few line breaks).
fprintf('x is equal to %s\n',num2str(x))
printing out a few scalar variables in matlab is a mess (see answer above). having a function like this in your search path helps:
function echo(varargin)
str = '';
for k=1:length(varargin)
str = [str ' ' num2str(varargin{k})];
end
disp(str)
just nest a sprintf() inside the disp().
disp(sprintf("X is equal to %d.",x));