What is the meaning of [] in a matlab function argument? [duplicate] - matlab

This question already has an answer here:
How to use reshape in Matlab?
(1 answer)
Closed 7 years ago.
I found the following function call:
reshape(A, 1, [])
This flattens matrix A colum major. I am trying to understand the call. The function documentation says after A there should be a size vector for the reshaped matrix, but in here there is a one followed by [] instead of a two-vector. Is this a way of saying "Do whatever it takes so the matrix will have one row, I don't care what the width is"?
How come Matlab lets you exchange one argument for two like this? I tried googling around and did not find an explanation, and I want to understand what's going on here.

[] is an empty matrix. In many MATLAB built-in functions, an empty matrix is interpreted to mean "use the default argument here" or "automatically determine this value". Occasionally it is used to disambiguate two meanings of a function, as with the max function, where max(A,2) compares each element of A to 2 and returns the larger, while max(A,[],2) finds the largest element of each row.
If you read the help for reshape, you will see the following:
You can specify a single dimension size of [] to have the dimension size automatically calculated, such that the number of elements in B matches the number of elements in A. For example, if A is a 10-by-10 matrix, then reshape(A,2,2,[]) reshapes the 100 elements of A into a 2-by-2-by-25 array.

Related

Selecting Matrix element using vector elements [duplicate]

This question already has answers here:
Use a vector as an index to a matrix
(3 answers)
Closed 4 years ago.
Is there a way in Matlab to select a matrix element based off the elements in a vector? I don't think my description is clear, but what I effectively want to do is something similar to:
A=zeros(3,3,3) %3d matrix
A(1,1,2)=5
b=[1,1,2]
A(b)=5
Meaning, some easy way to select one element from a matrix using the entries in a vector as arguments. This exact example does not work because the last line counts b as a single argument, not three. I could write A(b(1),b(2),b(3)) but what I'm really looking for here is if there's a nice way of doing.
Method 1: Use sub2ind to find the linear index
You can define a function called findLinearIndex such that it convert the vector elements to the linear index of A:
findLinearIndex = #(A,b) sub2ind(size(A), b(1), b(2), b(3))
A(findLinearIndex(A,b)) = 5
Method 2: Convert the vector to cell array by num2cell
Then, you can use {:} to get the index
b_cell = num2cell(b) ;
A(b_cell{:}) = 5

(matlab matrix operation), Is it possible to get a group of value from matrix without loop?

I'm currently working on implementing a gradient check function in which it requires to get certain index values from the result matrix. Could someone tell me how to get a group of values from the matrix?
To be specific, for a result matrx res with size M x N, I'll need to get element res(3,1), res(4,2), res(1,3), res(2,4)...
In my case, M is dimension and N is batch size and there's a label array whose size is 1xbatch_size, [3 4 1 2...]. So the desired values are res(label(:),1:batch_size). Since I'm trying to practice vectorization programming and it's better not using loop. Could someone tell me how to get a group of value without a iteration?
Cheers.
--------------------------UPDATE----------------------------------------------
The only idea I found is firstly building a 'mask matrix' then use the original result matrix to do element wise multiplication (technically called 'Hadamard product', see in wiki). After that just get non-zero element out and do the sum operation, the code in matlab should look like:
temp=Mask.*res;
desired_res=temp(temp~=0); %Note: the temp(temp~=0) extract non-zero elements in a 'column' fashion: it searches temp matrix column by column then put the non-zero number into container 'desired_res'.
In my case, what I wanna do next is simply sum(desired_res) so I don't need to consider the order of those non-zero elements in 'desired_res'.
Based on this idea above, creating mask matrix is the key aim. There are two methods to do this job.
Codes are shown below. In my case, use accumarray function to add '1' in certain location (which are stored in matrix 'subs') and add '0' to other space. This will give you a mask matrix size [rwo column]. The usage of full(sparse()) is similar. I made some comparisons on those two methods (repeat around 10 times), turns out full(sparse) is faster and their time costs magnitude is 10^-4. So small difference but in a large scale experiments, this matters. One benefit of using accumarray is that it could define the matrix size while full(sparse()) cannot. The full(sparse(subs, 1)) would create matrix with size [max(subs(:,1)), max(subs(:,2))]. Since in my case, this is sufficient for my requirement and I only know few of their usage. If you find out more, please share with us. Thanks.
The detailed description of those two functions could be found on matlab's official website. accumarray and full, sparse.
% assume we have a label vector
test_labels=ones(10000,1);
% method one, accumarray(subs,1,[row column])
tic
subs=zeros(10000,2);
subs(:,1)=test_labels;
subs(:,2)=1:10000;
k1=accumarray(subs,1,[10, 10000]);
t1=toc % to compare with method two to check which one is faster
%method two: full(sparse(),1)
tic
k2=full(sparse(test_labels,1:10000,1));
t2=toc

how to threshold/filter a vector? [duplicate]

This question already has an answer here:
Operands to the || and && operators must be convertible to logical scalar values
(1 answer)
Closed 9 years ago.
I have a vector containing a list of data (X and Y coords) which i want to compare to an array of 100 vectors (each with similar but not the same XY Coords) in order to find a match.
Each vector ranges in data size (between 10 and 20 cords) which causes issues when matching matrices of different sizes.
so in order to match i have used the matchfeatures which matches exact data which is no use as vectors different sizes.
so i made
(using pdist to turn cords into distances)
threshigh = (vector1/100) * 110;
threslow = (vector1/100) * 90;
if (Vector2 <= threshigh)&&(vector2 >= threslow)
disp its a match
else
not a match
end
this is perfect! but.. I cannot use operators on vectors as they only apply to scalar quantities.
how do i get around this?
it has also occurred to me even if this works and some values in the vector fall between this range it will not match unless they all do? how do i just take majority of results?
The link of the duplicate question should solve your first problem. As for your second issue:
... even if this works and some values in the vector fall between this range it will not match unless they all do? how do i just take majority of results?
Once you have a logical array (with 1's at the positions corresponding to elements that fall within the specified range, and 0's elsewhere), you can manipulate it to your liking.
In its current form, the if statement branches only if all elements are true (logical '1'). If you know that the tested expression might be a vector (that is, an array), you can do the following:
Use the any command to check if at least one element in the array is true:
if any(...)
%// Do something...
end
Use the all command to check if all elements are true:
if all(...)
%// Do something...
end
(using all here is superfluous, but it does enhance readability...)
Check for a majority of '1's by using mode:
if mode(double(...))
%// Do something...
end
mode returns the most frequent element in the array, so if it's '1' the if statement will branch.

MATLAB: apply a function to every n items in a vector

This related question How can I apply a function to every row/column of a matrix in MATLAB? seems to indicate one way to do this is using num2cell, which I kind of want to stay away from.
Here's what I want to do. I've got an index list for a triangle mesh, the indices index the vertex list.
I want to run func(a,b,c) on the first 3 indices, then the next three indices, and so on.
So I could reshape(idxs,3,[]) so now i've got my data into triplets as column vectors. But arrayfun does not do what I want it to do.
Looking for something like a column-map operator.
First, get your func properly vectorized, if necessary, such that the arguments can be lists of equal length:
vec_func = #(a,b,c)(arrayfun(#func,a,b,c))
Then, you can directly access every third element of idxs:
vec_func( idxs(1:3:end), idxs(2:3:end), idxs(3:3:end) )

Matlab: assign to matrix with column\row index pairs [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I change the values of multiple points in a matrix?
I have a matrix A and three vectors of the same length, r, holding the indexes of the rows to assign to, c, holding the indexes of the columns to assign to, and v containing the actual values to assign.
What I want to get is A(r(i),c(i))==v(i) for all i. But doing
A(r,c)=v;
Doesn't yield the correct result as matlab interprets it as choosing every possible combination of r and c and assigning values to it, for instance
n=5;
A=zeros(n);
r=1:n;
c=1:n;
A(r,c)=1;
Yields a matrix of ones, where I would like to get the identity matrix since I want A(r(i),c(i))==1 for each i, that is only elements on the diagonal should be affected.
How can I achieve the desired result, without a for loop?
OK, I've found the answer - one needs to use linear indexing, that is convert the column\row pairs into a single index:
idx = sub2ind(size(A), r,c);
A(idx)=v;