I looking for an explanation in a granular level to understand what the following code means:
idx=y==100;
From what I understand, it is taking a derivative of a variable x, setting it equal to y, equal to 100. Although, I'm not too sure what the purpose of this code would be.
For idx=y==100; MATLAB performs the following steps:
It determines which of the two operators, == and = is invoked first:
Since the == operator has a higher precedence than the = operator, it selects y==100. To learn about operator precedence, you can have a look at https://www.mathworks.com/help/matlab/matlab_prog/operator-precedence.html.
The operation y==100, then compares y to 100 and returns logical array of the same size as y having 1 at position where y is equal to 100 and 0 at other positions. To learn more about the == operator you can have a look at https://www.mathworks.com/help/matlab/ref/eq.html.
Finally, MATLAB invokes the = operator: idx= assigns the result of y==100 to the variable idx.
Related
isequaln() is testing symbolic objects for equality as stated in the documentation. However, this is not the case with the following script.
syms a
f1=cos(a)^2;
f2=1-sin(a)^2;
isequaln(f1,f2)
ans =
logical
0
MATLAB does not return the correct answer. What does MATLAB do when comparing equality for symbolic expressions, compare strings (i.e. a typical scenario for regular expressions), or something else?
At the bottom of the documentation page, there is a section called "Tips", which contains the following item:
isequaln(A,B) checks if A and B are the same size and their contents are syntactically the same expression, treating NaN values as equal. To check whether the mathematical comparison A == B holds for all values of variables in A and B, use isAlways(A == B).
(emphasis mine)
isAlways does what you want:
syms a
f1 = cos(a)^2;
f2 = 1-sin(a)^2;
isAlways(f1 == f2)
This outputs true.
Alternatives:
>> simplify(f1-f2)
ans =
0
>> simplify(f1==f2)
ans =
symtrue
I just found the statement any('') returns a logical 0, while the statement all('') returns a logical 1.
If the function any does not think the empty string ('') as nonzero, the function all should do the same, but from the result, the function all seems to think the empty string ('') as nonzero.
BTW, the similar thing happens where any(NaN) returns logical 0 while all(NaN) returns logical 1.
Is it a MATLAB bug?
Here is the version information of the MATLAB I am using.
MATLAB Version: 9.1.0.441655 (R2016b)
MATLAB License Number: DEMO
According to the Documentation
definition of any:
any(x) ...determines if any element is a nonzero number or logical 1 (true)
In practice, any is a natural extension of the logical OR operator.
If A is an empty 0-by-0 matrix, any(A) returns logical 0 (false).
and definition of all:
all(x) ...determines if the elements are all nonzero or logical 1 (true)
In practice, all is a natural extension of the logical AND operator.
If A is an empty 0-by-0 matrix, then all(A) returns logical 1 (true).
We can implement both functions:
function out = Any(V)
out = false;
for k = 1:numel(V)
out = out || (~isnan(V(k)) && V(k) ~= 0);
end
end
function out = All(V)
out = true;
for k = 1:numel(V)
out = out && (V(k) ~= 0);
end
end
Explanation:
-In any we assume that all elements are not nonzero [so all are zeros] and we want to prove that the assumption is wrong so we provide an initial value of false.
-Because any is a natural extension of the logical OR operator we use ||
-Because we should check for nonzero numbers we use V(k) ~= 0
-Because we should check for nonzeros numbers and NaN is Not a Number we use ~isnan(V(k)).
-In all we assume that all elements are nonzero [so all are ones] and we want to prove that the assumption is wrong so we provide an initial value of true
-Because all is a natural extension of the logical AND operator we use &&
-Because we should check for nonzeros we use V(k) ~= 0
-Because the definition of all doesn't force that nonzero elements to be numbers we don't use ~isnan(V(k))
Any returns 0 because it is not the case that any of its elements are true. An any clause is true if any of its elements are true.
All returns 1 because it is the case that all of its elements are true. All of its elements are true so long as none of its elements are false, and none of its elements are false.
It is convenient and consistent w.r.t the rest of your math when applying an associative operation over an empty list of values returns the neutral element of that operation. This is why
a sum of zero numbers is 0
a product of zero numbers is 1
a logical or of zero booleans is false
a logical and of zero booleans is true
Keywords for further reading: monoid, fold.
I just found solid proof from the documentation about the any and all functions, as follows.
Documentation of the function any
https://www.mathworks.com/help/matlab/ref/any.html
If A is an empty 0-by-0 matrix, any(A) returns logical 0 (false).
Documentation of the function all
https://www.mathworks.com/help/matlab/ref/all.html
If A is an empty 0-by-0 matrix, then all(A) returns logical 1 (true).
And the empty string in MATLAB is actually a 0×0 empty char array (I just found it). That explains my original question, from the documentation.
My goal is to compare two matrices: A and B in two different files:
function [Result]=test()
A_Mat= load('fileA', 'A')
B_Mat= load('fileB', 'B')
Result= A_Mat == B_Mat
end
The result that I want is a matrix that includes the difference between A and B.
The error that I have is:
error: binary operator '==' not implemented for 'scalar struct' by 'scalar struct' operations
The load function doesn't return what you think it returns. Reading the extensive and easily comprehensible MATLAB documentation always helps.
function Result=test()
load('fileA', 'A');
load('fileB', 'B');
Result = A == B
end
Use the isequal function.
isequal(A,B)
If you simply want the difference between A and B you should first use load as dasdingonesin suggested, and either check for full matrix equality with isequal or elementwise equality with ==. The difference, however, is simply given by - of course:
isequal(A,B); % returns a boolean for full matrix equality
A==B; % returns a logical matrix with element wise equality
A-B; % returns a matrix with differences between the two matrices
Do note that isequal can deal with matrices of unequal size (it will simply return 0), whilst both == and - will crash with the error Matrix dimensions must agree.
First, the operator == does work on matrices, and it returns a logical matrix of true/false (1/0) where the corresponding items are equal or different respectively. From the error you got it seems that you didn't read matrices from the file, but structs, and indeed, == doesn't work for structs.
You can use isequal for both structs and matrices. This function returns only one value - 1 or 0 (true/false).
ADDED
After seeing #dasdingonesin answer, who actually pointed to the exact problem, I just wanted to add that when you write
A_Mat= load('fileA', 'A')
it returns a struct as with the field A.
So:
A_Mat = s.A
I have a simple problem that I'm looking for a fast implementation in Matlab. I have an array of values, let's say:
a = floor(rand(5,5).*255)
I then have a similarly sized threshold array, let's say it's:
a_thresh = floor(rand(5,5).*255)
For values within a if they are 0.5x smaller than the corresponding value in a_thresh I want the output to be 0 - similarly for 1.2x the value in a_thresh should also be set to zero, i.e.:
a(a < a_thresh.*0.4) = 0
a(a > a_thresh.*1.2) = 0
For values between 0.4x and 0.5x and 1.0x and 1.2x I want a proportional amount and else where between 0.5 and 1.0 I want to use the value of a unaltered. I thought I could use something like the following:
a(a>= a_thresh .* 0.4 && a <a_thresh.* 0.5) = ((a - a_thresh.*0.4)/(a_thresh.*0.5 a_thresh.*0.4)) .* a;
However, I get an error that says:
Operands to || and && operations must be convertible to logical scalar values
Any advice on how to solve this? Obviously I could use loops to do this and it would be trivial, but I want to keep the code vectorized.
The thing about && is that it can operate only on scalars, whereas & can operate on arrays as well. You should change the && to & to make it work (you can read more about it in this question).
Update:
Regarding your second problem described in a comment: the number of elements on the left is different because you're using indices (selecting only certain elements), and on the right you're working with the entire matrix a and a_thresh.
You need to use indices in both sides, so I suggest storing it in a variable and then use it as an array subscript, along these lines:
idx = (a >= a_thresh*0.4 & a < a_thresh*0.5);
a(idx) = ((a(idx)-a_thresh(idx)*0.4) ./ (a_thresh(idx)*0.5*a_thresh(idx)*0.4)) .* a(idx);
I'm not sure if the calculation itself is correct, so I'll leave it to you to check.
I have a mesh grid defined as
[X, Y, Z] = meshgrid(-100:100, -100:100, 25); % z will have more values later
and two shapes (ovals, in this case):
x_offset_1 = 40;
x_offset_2 = -x_offset_1;
o1 = ((X-x_offset_1).^2./(2*Z).^2+Y.^2./Z.^2 <= 1);
o2 = ((X-x_offset_2).^2./(2*Z).^2+Y.^2./Z.^2 <= 1);
Now, I want to find all points that are nonzero in either oval. I tried
union = o1+o2;
but since I simply add them, the overlapping region will have a value of 2 instead of the desired 1.
How can I set all nonzero entries in the matrix to 1, regardless of their previous value?
(I tried normalized_union = union./union;, but then I end up with NaN in all 0 elements because I'm dividing by zero...)
Simplest solution: A=A~=0;, where A is your matrix.
This just performs a logical operation that checks if each element is zero. So it returns 1 if the element is non-zero and 0 if it is zero.
First suggestion: don't use union as a variable name, since that will shadow the built-in function union. I'd suggest using the variable name inEitherOval instead since it's more descriptive...
Now, one option you have is to do something like what abcd suggests in which you add your matrices o1 and o2 and use the relational not equal to operator:
inEitherOval = (o1+o2) ~= 0;
A couple of other possibilities in the same vein use the logical not operator or the function logical:
inEitherOval = ~~(o1+o2); % Double negation
inEitherOval = logical(o1+o2); % Convert to logical type
However, the most succinct solution is to apply the logical or operator directly to o1 and o2:
inEitherOval = o1|o2;
Which will result in a value of 1 where either matrix is non-zero and zero otherwise.
There is another simple solution, A=logical(A)