Matlab: Add vectors not in the same length to a matrix - matlab

Is it possible to automatically add vectors that are not in the same length together for a matrix?
i.e:
a = [1 2 3 4]
b = [1 2]
How can I make C to be:
c = [1 2 3 4 ; 1 2 0 0]
or
c = [1 2 3 4 ; 1 2 NaN NaN]
or something like that
Thanks

This might help
a = [1 2 3 4];
b = [1 2];
c = a;
c(2,1:length(b)) = b;
c =
1 2 3 4
1 2 0 0
then, if you'd rather have NaN than 0, you could do what Dennis Jaheruddin suggests in a comment below.

Make a function like this
function out = cat2(a, b)
diff = length(a) - length(b)
if diff > 0
b = [b, nan(1, diff)];
else
a = [a, nan(1, -diff)];
end
out = [a;b];
end
(but also add a check to handle column vectors too)
cat2([1 2 3 4], [1 2])
ans =
1 2 3 4
1 2 NaN NaN

Related

Create a matrix by sliding down a given vector by one step for every column

Given this vector
a = [1 2 3 4]
I want to create a matrix like this
b = [1 0 0 0;
2 1 0 0;
3 2 1 0;
4 3 2 1;
0 4 3 2;
0 0 4 3;
0 0 0 4]
in a vectorized way not using loops.
Hint: use conv2 (hover mouse to see code):
a = [1 2 3 4];
b = conv2(a(:), eye(numel(a)));
Or, in a similar mood, you can use convmtx (from the Signal Processing Toolbox):
a = [1 2 3 4];
b = convmtx(a(:), numel(a));
One way to do it:
a = [1 2 3 4]
n = numel(a);
%// create circulant matrix from input vector
b = gallery('circul',[a zeros(1,n-1)]).' %'
%// crop the result
c = b(:,1:n)
Another way:
b = union( tril(toeplitz(a)), triu(toeplitz(fliplr(a))),'rows','stable')
or its slightly variation
b = union( toeplitz(a,a.*0),toeplitz(fliplr(a),a.*0).','rows','stable')
and probably even faster:
b = [ toeplitz(a,a.*0) ; toeplitz(fliplr(a),a.*0).' ]
b(numel(a),:) = []
With bsxfun -
na = numel(a)
b = zeros(2*na-1,na)
b(bsxfun(#plus,[1:na]',[0:na-1]*2*na)) = repmat(a(:),1,na)
If you are looking for a faster pre-allocation, you can do -
b(2*na-1,na) = 0;.
Another bsxfun -
a=[1 2 3 4];
m=numel(a);
b=[a,zeros(1,m-1)].';
Q=bsxfun(#circshift, b, [0:m-1])

How to find one value from a matrix

0I have on matrix-
A=[1 2 2 3 5 5;
1 5 5 8 8 7;
2 9 9 3 3 5];
From matrix i need to count now many nonzero elements ,how any 1,how many 2 and how many 3 in each row of given matrix"A".For these i have written one code like:
[Ar Ac]=size(A);
for j=1:Ar
for k=1:Ac
count(:,j)=nnz(A(j,:));
d(:,j)=sum(A(j,:)== 1);
e(:,j)=sum(A(j,:)==2);
f(:,j)=sum(A(j,:)==3);
end
end
but i need to write these using on loop i.e. here i manually use sum(A(j,:)== 1),sum(A(j,:)== 2) and sum(A(j,:)== 3) but is there any option where i can only write sum(A(j,:)== 1:3) and store all the values in the different row i.e, the result will be like-
b=[1 2 1;
1 0 0;
0 1 2];
Matlab experts need your valuable suggestions
Sounds like you're looking for a histogram count:
U = unique(A);
counts = histc(A', U)';
b = counts(:, ismember(U, [1 2 3]));
Example
%// Input matrix and vector of values to count
A = [1 2 2 3 5 5; 1 5 5 8 8 7; 2 9 9 3 3 5];
vals = [1 2 3];
%// Count values
U = unique(A);
counts = histc(A', U)';
b = counts(:, ismember(U, vals));
The result is:
b =
1 2 1
1 0 0
0 1 2
Generalizing the sought values, as required by asker:
values = [ 1 2 3 ]; % or whichever values are sought
B = squeeze(sum(bsxfun(#(x,y) sum(x==y,2), A, shiftdim(values,-1)),2));
Here is a simple and general way. Just change n to however high you want to count. n=max(A(:)) is probably a good general value.
result = [];
n = 3;
for col= 1:n
result = [result, sum(A==col, 2)];
end
result
e.g. for n = 10
result =
1 2 1 0 2 0 0 0 0 0
1 0 0 0 2 0 1 2 0 0
0 1 2 0 1 0 0 0 2 0
Why not use this?
B=[];
for x=1:size(A,1)
B=[B;sum(A(x,:)==1),sum(A(x,:)==2),sum(A(x,:)==3)];
end
I'd do this way:
B = [arrayfun(#(i) find(A(i,:) == 1) , 1:3 , 'UniformOutput', false)',arrayfun(#(i) find(A(i,:) == 2) , 1:3 , 'UniformOutput', false)',arrayfun(#(i) find(A(i,:) == 3) , 1:3 , 'UniformOutput', false)'];
res = cellfun(#numel, B);
Here is a compact one:
sum(bsxfun(#eq, permute(A, [1 3 2]), 1:3),3)
You can replace 1:3 with any array.
you can make an anonymous function for it
rowcnt = #(M, R) sum(bsxfun(#eq, permute(M, [1 3 2]), R),3);
then running it on your data returns
>> rowcnt(A,1:3)
ans =
1 2 1
1 0 0
0 1 2
and for more generalized case
>> rowcnt(A,[1 2 5 8])
ans =
1 2 2 0
1 0 2 2
0 1 1 0

how to get values of a matrix in MATLAB where the indices are given in a nx2 array

I have a matrix A of size nRows x nCols.
I have a nx2 matrix B which contains indices of the matrix A.
I want to get the values of A at the indices given in B.
lets say,
B = [1, 2;
2, 3;
3, 4]
A(1,2) = 1
A(2,3) = 2
A(3,4) = 1
I want to know any Matlab command which gives the following, given A and B (I don't want to use loops):
[1 2 1]
I guess this is what you are looking for:
A(sub2ind(size(A),B(:,1),B(:,2)))
This is what you want:
A = [1,2; 3, 4; 5, 6; 7,8; 9,0]; % this is your N by 2 matrix
B = [1,1; 1,2; 2,1; 3, 1; 4,2]; % these are your indexes
A(sub2ind(size(A), B(:,1), B(:,2)))
A =
1 2
3 4
5 6
7 8
9 0
B =
1 1
1 2
2 1
3 1
4 2
ans =
1
2
3
5
8

Expand a matrix with polynomials

Say I have a matrix A with 3 columns c1, c2 and c3.
1 2 9
3 0 7
3 1 4
And I want a new matrix of dimension (3x3n) in which the first column is c1, the second column is c1^2, the n column is c1^n, the n+1 column is c2, the n+2 column is c2^2 and so on. Is there a quickly way to do this in MATLAB?
Combining PERMUTE, BSXFUN, and RESHAPE, you can do this quite easily such that it works for any size of A. I have separated the instructions for clarity, you can combine them into one line if you want.
n = 2;
A = [1 2 9; 3 0 7; 3 1 4];
[r,c] = size(A);
%# reshape A into a r-by-1-by-c array
A = permute(A,[1 3 2]);
%# create a r-by-n-by-c array with the powers
A = bsxfun(#power,A,1:n);
%# reshape such that we get a r-by-n*c array
A = reshape(A,r,[])
A =
1 1 2 4 9 81
3 9 0 0 7 49
3 9 1 1 4 16
Try the following (don't have access to Matlab right now), it should work
A = [1 2 9; 3 0 7; 3 1 4];
B = [];
for i=1:n
B = [B A.^i];
end
B = [B(:,1:3:end) B(:,2:3:end) B(:,3:3:end)];
More memory efficient routine:
A = [1 2 9; 3 0 7; 3 1 4];
B = zeros(3,3*n);
for i=1:n
B(3*(i-1)+1:3*(i-1)+3,:) = A.^i;
end
B = [B(:,1:3:end) B(:,2:3:end) B(:,3:3:end)];
Here is one solution:
n = 4;
A = [1 2 9; 3 0 7; 3 1 4];
Soln = [repmat(A(:, 1), 1, n).^(repmat(1:n, 3, 1)), ...
repmat(A(:, 2), 1, n).^(repmat(1:n, 3, 1)), ...
repmat(A(:, 3), 1, n).^(repmat(1:n, 3, 1))];

From matrix column subtract corresponding vector value

I have a matrix 'x' and a row vector 'v'; the number of elements in the row vector is the same as the number of columns in the matrix. Is there any predefined function for doing the following operation?
for c = 1 : columns(x)
for r = 1 : rows(x)
x(r, c) -= v(c);
end
end
bsxfun(#minus,x,v)
Here's an octave demonstration:
octave> x = [1 2 3;2 3 4]
x =
1 2 3
2 3 4
octave> v = [2 0 1]
v =
2 0 1
octave>
octave> z=bsxfun(#minus,x,v)
z =
-1 2 2
0 3 3
If you are using Octave 3.6.0 or later, you don't have to use bsxfun since Octave performs automatic broadcasting (note that this is the same as actually using bsxfun, just easier on the eye). For example:
octave> x = [1 2 3; 2 3 4]
x =
1 2 3
2 3 4
octave> v = [2 0 1]
v =
2 0 1
octave> z = x - v
z =
-1 2 2
0 3 3
Alternatively, you can replicate your vector and directly subtract it from the matrix
z = x-repmat(v, size(x, 1), 1);