Logical indexing: What is going on here? - matlab

I have read this documentation on logical indexing, but it doesn't clarify my problem.
I have this line of code:
y = rand(20,3);
aa= unidrnd(2,20,3) - 1;
val = ( aa & y<1.366e-04) | (~aa & y<8.298e-04);
aa(val) = ~aa(val);
I cannot understand what is going on in the last line aa(val) = ~aa(val);.
A similar question was asked here but it does not answer the question to the logical indexing specifically or what the logical values were implying.
when the code is run, val's elements are zeroes.
Here's the tricky part, if I run only aa(val) or ~aa(val) I get Empty matrix: 0-by-1. But if I run the entire line aa(val) = ~aa(val);, i get a matrix aa(with 0's and 1's, 20x3).
'~' is performing the inversion of the values right? That means it should be assigning a matrix of 1's (20x3). But apparently it is not!!I
Can someone please breakdown to me what is happening in the last line.

If all of val's elements are zeros (actually logical falses or you would get an error), then indexing aa by val would return nothing (as you point out). So when you do the whole line
aa(val) = ~aa(val)
it is essentially assigning the inverse of nothing to nothing and hence it doesn't do anything and should return aa unchanged. Remember that the ~ is being applied to aa(val) and NOT to val itself so it inverts the empty matrix aa(val) and then assigns this to the empty matrix aa(val).

Related

Matlab matrix multiplication returns values that it shouldn't

I have a problem using matrix multiplication in Matlab.
I have a 8x4 matrix called A and a 4x1 vector called B. Looking at matrix A, the fourth row of has the values
A(4,:) = (-19.723654104483987, -73.609679228848705, 73.609679228848705, 19.723654104483987)
and the vector B has the values
B = (101325, 101325, 101325, 101325)'.
It appears to me that these two, when multiplied, would cancel eachother out. However, when I use A*B = ans, the fourth row of ans has a value as shown below.
ans(4) = 4.656612873077393e-10
I find this strange since I tried to check if the elements of A(4,:) and they really should cancel out since
(A(4,1) == -A(4,4)) = 1
(A(4,2) == -A(4,3)) = 1
and
(B(1) == B(2)) = 1
(B(1) == B(3)) = 1
(B(1) == B(4)) = 1
I was thinking that it might have something to do with the machine epsilon of Matlab, but the answer is larger than e-16.
Another thing I find strange is that when I use A(4,:)*B it returns 0. Why does a value appear on the forth row when using full scale matrix multiplication?
If anyone has an idea why this doesn't return zero, I would be grateful!
You are computing an expression
((-a+(-b))+b)+a, a,b > 0
Floating point operations are not commutative, the truncation error committed by the first addition of -a and -b is not undone by the second addition of b, so the third addition of a will not land at zero, but will reflect the truncation error of the first sum. So it is not surprising that you get a residual error of size (a+b)*mu, mu being the machine constant, about 2e-16. As your a+b is about 1e+7, this conforms with the actual result you got.
See also the many resources provided in Is floating point math broken?

deleting a column in hansl

I have a very simple question. I want to delete a column from a matrix in a loop.
In Matlab I use the following:
for a certain i,
X(:,i)=[]
which deletes the column an reshapes the matrix.
I want to know the equivalent in Hansl (Gretl) program, please.
Thanks!
Sorry it's probably too late for you now, but I just saw your question and maybe it's useful for others.
In hansl (gretl's scripting and matrix language) I could think of several possibilities:
First, if you happen to know the number of columns and the value of i, the solution could use a hard-wired index vector (for i==2 and cols(X)==5 here):
X = X[, {1, 3,4,5}]
Secondly, since the first solution is probably too restrictive, you could concatenate the left and right parts of the matrix, as in:
X = X[, 1: i-1] ~ X[, i+1 :cols(X)]
But the problem here is that i must not index the first or last column, or the indexing will produce an error.
So my final suggestion that should work universally is:
X = selifc( X, ones(1, i-1) ~ 0 ~ ones(1, cols(X) - i) )
The selifc() function discards the column for which the second vector argument has a 0 entry. This also works for i==1 or i==cols(X).
A shorter variation of this final solution might be:
X = selifc(X, seq(1, cols(X)) .!= i)
which does an element-wise not-equal-to-i comparison (.!=) of the column indices constructed with the seq() function. But it's probably not as readable as the previous way.
good luck!

find returns empty matrix

I have two vectors which are of length 200,000 approximately. They consist of dates in the datenum format.
%datenums
date_exp = datenum(data_exp(:,1:6));
date_sim = datenum(data_sim(:,1:6));
I want to find the dates in date_exp that exists in date_sim.
Then remove the values from date_exp
I have used the the ismember tool but ending up at i=38 find retunrs: Improper assignment with rectangular empty matrix.
Error in filter (line 18)
c(i)= find(ismember(date_sim(:),date_exp(i)),1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
c = zeros(length(date_sim),1);
for i=1:length(date_sim)
c(i)= find(ismember(date_sim(:),date_exp(i)),1);
if isempty(c(i)) == 1
c(i) = 0;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I would be really helpful if anyone could help me out here.
The issue is because date_exp(38) must not be within date_sim. When there are no 1's in the input, find returns an empty array ([]).
Your code does not handle this as you would expect though because of this line.
c(i) = find(...)
In this case, if there are no matches (find() == []), then you are essentially calling
c(i) = [];
This deletes the ith element of c element
Therefore the following line is never true!
if isempty(c(i)) == 1
Instead, you should probably do something to handle the empty value.
index = find(ismember(date_sim(:), date_exp(i)), 1);
%// Only assign the index if it isn't an empty array
if ~isempty(index)
c(i) = index;
end
You don't have to worry about assigning zeros because your initial matrix is already full of zeros.
A Better Option
All of that aside, it would likely be a much better approach to not loop at all and to instead use the second output of ismember (on the arrays before you pass them to datenum) to give you the same result in a much more efficient way.
[~, c] = ismember(date_exp(:,1:6), date_sim(:,1:6), 'rows');

i cannot understand MATLAB syntax

In MATLAB, i was faced with a incomprehensible syntax.
for i = [1:n-1,n+1:N]
Z{i} = U{i}(:,r);
end
if you knows exactly, please let me know.
(if you show some example(e.g. when n=1, N=3), i can understand your explain easily.)
This syntax basically means:
for i = [1:n-1,n+1:N]
This just means that i will sequentially take the values defined in the array:
1 till n-1 increasing by 1 and after it will continue from n+1 till N. It will skip n in other words.
Z{i} = U{i}(:,r);
{ represent cells so the ith cell of Z (imagine Z and U as cell arrays) will be assigned the content of ith cell of U from which it will keep though only the r-th column (I guess its a matrix of some kind).

Corner Cases, Unexpected and Unusual MATLAB [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Over the years, reading others code, I encountered and collected some examples of MATLAB syntax which can be at first unusual and counterintuitive. Please, feel free to comment or complement this list. I verified it with r2006a.
MATLAB always returns first output argument of a function (if it has at least one) into its caller workspace, also unexpectedly if function is being called without returning arguments like myFunc1(); myFunc2(); the caller workspace still would contain first output of myFunc2(); as "invisible" ans variable. It could play an important role if ans is a reference object - it would remain alive.
set([], 'Background:Color','red')
MATLAB is very forgiving sometimes. In this case, setting properties to an array of objects works also with nonsense properties, at least when the array is empty. Such arrays usually come from harray = findobj(0,'Tag','NotExistingTag')
myArray([1,round(end/2)])
This use of end keyword may seem unclean but is sometimes very handy instead of using length(myArray).
any([]) ~= all([])
Surprisigly any([]) returns false and all([]) returns true. And I always thought that all is stronger then any.
EDIT:
with not empty argument all() returns true for a subset of values for which any() returns true (e.g. truth table). This means that any() false implies all() false. This simple rule is being violated by MATLAB with [] as argument.
Loren also blogged about it.
Select(Range(ExcelComObj))
Procedural style COM object method dispatch. Do not wonder that exist('Select') returns zero!
[myString, myCell]
MATLAB makes in this case an implicit cast of string variable myString to cell type {myString}. It works, also if I would not expect it to do so.
[double(1.8), uint8(123)] => 2 123
Another cast example. Everybody would probably expect uint8 value being cast to double but Mathworks have another opinion. Without a warning this behavior is very dangerous.
a = 5;
b = a();
It looks silly but you can call a variable with round brackets. Actually it makes sense because this way you can execute a function given its handle.
Syntax Foo(:) works not only on data but also with functions if called as Bar.Foo(:), in this scenario the function input argument is passed as char colon ':'.
For example let Bar.Foo = #(x) disp(x)
Now calling Bar.Foo(:) prints char ':' in the MATLAB Command Window.
This strange feature works with all MATLAB 7 versions without warnings.
a = {'aa', 'bb'
'cc', 'dd'};
Surprsisingly this code neither returns a vector nor rises an error but defins matrix, using just code layout. It is probably a relict from ancient times.
EDIT: very handy feature, see the comment by gnovice.
set(hobj, {'BackgroundColor','ForegroundColor'},{'red','blue'})
This code does what you probably expect it to do. That function set accepts a struct as its second argument is a known fact and makes sense, and this sintax is just a cell2struct away.
Equvalence rules are sometimes unexpected at first. For example 'A'==65 returns true (although for C-experts it is self-evident). Similarly isequal([],{}) retuns, as expected, false and isequal([],'') returns true.
The string-numeric equivalence means that all string functions can be used also for numeric arrays, for example to find indices of a sub-array in a large array:
ind = strfind( [1 2 3 4 1 2 3 4 1 2 3 4 ], [2 3] )
MATLAB function isnumeric() returns false for booleans. This feels just ... false :-)
About which further unexpected/unusual MATLAB features are you aware?
Image coordinates vs plot coordinates Used to get me every time.
%# create an image with one white pixel
img = zeros(100);
img(25,65) = 1;
%# show the image
figure
imshow(img);
%# now circle the pixel. To be sure of the coordinate, let's run find
[x,y] = find(img);
hold on
%# plot a red circle...
plot(x,y,'or')
%# ... and it's not in the right place
%# plot a green circle with x,y switched, and it works
plot(y,x,'og')
Edit 1
Array dimensions
Variables have at least two dimensions. Scalars are size [1,1], vectors are size [1,n] or [n,1]. Thus, ndims returns 2 for any of them (in fact, ndims([]) is 2 as well, since size([]) is [0,0]). This makes it a bit cumbersome to test for the dimensionality of your input. To check for 1D arrays, you have to use isvector, 0D arrays need isscalar.
Edit 2
Array assignments
Normally, Matlab is strict with array assignments. For example
m = magic(3);
m(1:2,1:3) = zeros(3,2);
throws a
??? Subscripted assignment dimension mismatch.
However, these work:
m(1:2,1:2) = 1; %# scalar to vector
m(2,:) = ones(3,1); %# vector n-by-1 to vector 1-by-n (for newer Matlab versions)
m(:) = 1:9; %# vector to 'linearized array'
Edit 3
Logical indexing with wrongly sized arrays Good luck debugging this!
Logical indexing seems to make a call to find, since your logical array doesn't need the same amount of elements as there are indices!
>> m = magic(4); %# a 4-by-4 array
>> id = logical([1 1 0 1 0])
id =
1 1 0 1 0
>> m(id,:) %# id has five elements, m only four rows
ans =
16 2 3 13
5 11 10 8
4 14 15 1
%# this wouldn't work if the last element of id was 1, btw
>> id = logical([1 1 0])
id =
1 1 0
>> m(id,:) %# id has three elements, m has four rows
ans =
16 2 3 13
5 11 10 8
Instead of listing examples of weird MATLAB syntax, I'll address some of the examples in the question that I think make sense or are expected/documented/desired behavior.
How ANY and ALL handle empty arguments:
The result of any([]) makes sense: there are no non-zero elements in the input vector (since it's empty), so it returns false.
The result of all([]) can be better understood by thinking about how you might implement your own version of this function:
function allAreTrue = my_all(inArray)
allAreTrue = true;
N = numel(inArray);
index = 1;
while allAreTrue && (index <= N)
allAreTrue = (inArray(index) ~= 0);
index = index + 1;
end
end
This function loops over the elements of inArray until it encounters one that is zero. If inArray is empty, the loop is never entered and the default value of allAreTrue is returned.
Concatenating unlike classes:
When concatenating different types into one array, MATLAB follows a preset precedence of classes and converts values accordingly. The general precedence order (from highest to lowest) is: char, integer (of any sign or number of bits), single, double, and logical. This is why [double(1.8), uint8(123)] gives you a result of type uint8. When combining unlike integer types (uint8, int32, etc.), the left-most matrix element determines the type of the result.
Multiple lines without using the line continuation operator (...):
When constructing a matrix with multiple rows, you can simply hit return after entering one row and enter the next row on the next line, without having to use a semicolon to define a new row or ... to continue the line. The following declarations are therefore equivalent:
a = {'aa', 'bb'
'cc', 'dd'};
a = {'aa', 'bb'; ...
'cc', 'dd'};
a = {'aa', 'bb'; 'cc', 'dd'};
Why would you want MATLAB to behave like this? One reason I've noticed is that it makes it easy to cut and paste data from, for example, an Excel document into a variable in the MATLAB command window. Try the following:
Select a region in an Excel file and copy it.
Type a = [ into MATLAB without hitting return.
Right-click on the MATLAB command window and select "Paste".
Type ]; and hit return. Now you have a variable a that contains the data from the rows and columns you selected in the Excel file, and which maintains the "shape" of the data.
Arrays vs. cells
Let's look at some basic syntax to start with. To create an array with elements a, b, c you write [a b c]. To create a cell with arrays A, B, C you write {A B C}. So far so good.
Accessing array elements is done like this: arr(i). For Cells, it's cell{i}. Still good.
Now let's try to delete an element. For arrays: arr(i) = []. Extrapolating from examples above, you might try cell{i} = {} for cells, but this is a syntax error. The correct syntax to delete an element of a cell is, in fact, the very same syntax you use for arrays: cell(i) = [].
So, most of the time you access cells using special syntax, but when deleting items you use the array syntax.
If you dig deeper you'll find that actually a cell is an array where each value is of a certain type. So you can still write cell(i), you'll just get {A} (a one-valued cell!) back. cell{i} is a shorthand to retrieve A directly.
All this is not very pretty IMO.