I have a cell array containing matrices. I would like to get a 1-D row vector of the lengths of every element in the cell array. Example:
a = {[1, 2], [1, 8], [5, 2, 4]};
% b = ...?
b == [ 2, 2, 3 ]
Is this possible without using a for loop?
cellfun is your friend.
b = cellfun( #numel, a );
Related
I have not seen this in MATLAB. Suppose I have
V1 = [1 0], V2 = [0 1]
I want to create a matrix such that the matrix has to be
[[1 0] [0 1]
[0 1] [0 2]]
i.e., the first row and column are [V1 V2], element (2,2) of the matrix is [0 1]+[0 1]=[0 2]
So index (1,1) of the matrix should be [1 0], index (1,2) of matrix should be [0 1].
Is there any way I can implement this in MATLAB?
A matrix can only contain one value per element. Here are 3 options for how you could get close to what you've described:
You could create a 4*4 matrix like so:
V1 = [1 0]; V2 = [0 1];
M = [V1, V2; V2, 2*V2];
And then create a shorthand function to index this in blocks of 2
Mb = #(r,c) M( r, 2*c-1+[0,1] );
Mb(1,1); % = [1 0]
Mb(1,2); % = [0 1]
Mb(2,2); % = [0 2]
Note that this doesn't work for assignment back to M in blocks of 2, just for reading the value.
Alternatively, you could use a cell array
C = {V1, V2; V2, 2*V2};
Now you can index this how you want, but it won't behave as a single matrix, and you can't do numerical operations on the whole cell array
C{2,2}; % = [2, 2], note the curly brace indexing
A third option would be to make your matrix 3D
V1 = reshape( V1, 1, 1, [] );
V2 = reshape( V2, 1, 1, [] );
M3D = [V1, V2; V2, 2*V2];
Now you can index in the 3rd dimension
M3D(2,2,:); % = [0 2], but size [1,1,2]. Could reshape(M3D(2,2,:),1,[]) to get a row.
I would like to do the equivalent of
x = [1, 0, 3; 2, 3, 0; 0, 0, 3];
[yy, xx, vals] = find(x);
where I really need the vals variable. I need all three, but vals is important. Now consider the 3d case, and flip one, so it's more interesting.
x = repmat(x, [1, 1, 3]);
x(:, :, 2) = fliplr(x(:, :, 1));
I'd like to do the same as before. I found this in several places
[yy, xx, zz] = ind2sub(size(x), find(x));
but then I don't know how to extract vals properly... I also don't really care about zz, but I'm sure they somehow need to be used for indexing.
Any help would be appreciated.
find with one output argument, as you used in your last statement:
[yy, xx, zz] = ind2sub(size(x), find(x));
returns linear indices into the matrix. You can use these to index:
index = find(x);
vals = x(index);
[xx,yy,zz] = ind2sub(size(x), index);
I'm not sure I've understood what you want to achieve, nevertheless, considering your last matrix x
x = [1, 0, 3; 2, 3, 0; 0, 0, 3]
z = repmat(x, [1, 1, 3]);
x(:, :, 2) = fliplr(x(:, :, 1))
with
[yy, xx, vals] = find(x)
you have:
yy the indices of the rows of the found elements
xx the indices of the columns of the found elements
then you can use
lin_idx=sub2ind(size(x),yy,xx)
to get the linear indices of the values inside the matrix x
now you can use
[a,b,c]=ind2sub(size(x),lin_idx)
to get the 3D indices of the elements in the matrix
You can access the values using that indices:
for i=1:length(a)
k(i)=x(a(i),b(i),c(i))
end
Now the array k contains the values (as per the array vals returned by find).
I have three vectors in matlab:
x=[2, 3, 2, 3, 3]
y=[1, 5, 1, 5, 5]
Q=[7, 8, 4, 6, 8]
The modified vectors should be
x=[2, 3]
y=[1, 5]
Q=[12, 22 ]
Here x,y represents coordinates and Q a value depending upon (x,y).
The coordinates are getting repeated, like (2,1) has come twice, then I need to modify the vectors x and y representing unique coordinates and summing the values of Q for the particular coordinates e.g. (2,1) has come twice and the values of Q at those coordinates are 7 and 5 then for modified vectors coordinate (2,1) has to come once and corresponding Q value 7+5=12 and similarly for (3,5) Q is 8+6+8=22.
[XY, ~, ic] = unique([x' y'],'rows')
xu = XY(:,1).'; % The unique x you want
yu = XY(:,2).'; % The unique y you want
Qu = accumarray(ic,Q').';
I have two arrays say X and Y with same dimension. I can plot each points (x,y) by plot(X,Y). But how can I color them according to their given labels?
Say X = [3, 4, 2, 5, 6], Y = [2, 2, 1, 5, 6] and label = [1, 2, 2, [1,2], 2]. Here I all have to do is to color points with label=1 with blue and points in label=2 by red. How can I do this?
There are several ways to optimize this code and even get away without using the loop but this should get you started
for i=1:length(X)
xdot=X(i)
ydot=Y(i)
Ldot=label(i)
col=[1 0 0;0 0 1];
plot(xdot,ydot,'color',col(Ldot,:),'marker','o');
hold on
end
% CAT(2,A,B) is the same as [A,B].
% CAT(1,A,B) is the same as [A;B].
Seems I need to know this to understand what cat does.
[A,B]
is a matrix formed by placing B to the right of A, while
[A;B]
is a matrix formed by placing B below A.
Learn also about horzcat and vertcat.
[A, B] does col cat
[A; B] does row cat
eg:
x = [1, 2, 3];
y = [7, 8, 9];
[x, y] == > [1, 2, 3, 7, 8, 9]
becomes a 1x6 array
[x; y] == > [1, 2, 3]
[7, 8, 9]
becomes a 2x3 array
Just try it in Matlab and open ans to see the difference