Vectorization instead of for loop in Octave [duplicate] - matlab

Is there a matlab function which allows me to do the following operation?
x = [1 2 2 3];
and then based on x I want to build the matrix m = [1 2 2 3; 1 2 2 3; 1 2 2 3; 1 2 2 3]

You are looking for the REPMAT function:
x = [1 2 2 3];
m = repmat(x,4,1);
You can also use indexing to repeat the rows:
m = x(ones(4,1),:);
or even outer-product:
m = ones(4,1)*x;
and also using BSXFUN:
m = bsxfun(#times, x, ones(4,1))

You could try using vertcat, like this:
x = [1 2 2 3];
m = vertcat(x,x,x,x);
Or even simply:
x = [1 2 2 3];
m = [x;x;x;x];
EDIT:
for multiples of x, you can do:
x = [1 2 2 3];
m = [x;2*x;3*x]; % [1 2 2 3; 2 4 4 6; 3 6 6 9]
EDIT2:
For an arbitrary number of x's in m...
n = 3; % number of repetitions...
x = [1 2 2 3];
m = [];
for i=1:n
m = [m;x];
end

Related

Vectorize code in MATLAB

How to vectorize this code in MATLAB?
n = 3;
x = zeros(n);
y = x;
for i = 1:n
x(:,i) = i;
y(i,:) = i;
end
I am not able to vectorize it. Please help.
You can use meshgrid :
n = 3;
[x,y] = meshgrid(1:n,1:n)
x =
1 2 3
1 2 3
1 2 3
y =
1 1 1
2 2 2
3 3 3
n=3;
[x,y]=meshgrid(1:n);
This uses meshgrid which does this automatically.
Or you can use bsxfun as Divakar suggests:
bsxfun(#plus,1:n,zeros(n,1))
Just as a note on your initial looped code: it's bad practise to use i as a variable
If I can add something to the mix, create a row vector from 1 to n, then use repmat on this vector to create x. After, transpose x to get y:
n = 3;
x = repmat(1:n, n, 1);
y = x.';
Running this code, we get:
>> x
x =
1 2 3
1 2 3
1 2 3
>> y
y =
1 1 1
2 2 2
3 3 3

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 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

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);

Building a matrix by merging the same row vector multiple times

Is there a matlab function which allows me to do the following operation?
x = [1 2 2 3];
and then based on x I want to build the matrix m = [1 2 2 3; 1 2 2 3; 1 2 2 3; 1 2 2 3]
You are looking for the REPMAT function:
x = [1 2 2 3];
m = repmat(x,4,1);
You can also use indexing to repeat the rows:
m = x(ones(4,1),:);
or even outer-product:
m = ones(4,1)*x;
and also using BSXFUN:
m = bsxfun(#times, x, ones(4,1))
You could try using vertcat, like this:
x = [1 2 2 3];
m = vertcat(x,x,x,x);
Or even simply:
x = [1 2 2 3];
m = [x;x;x;x];
EDIT:
for multiples of x, you can do:
x = [1 2 2 3];
m = [x;2*x;3*x]; % [1 2 2 3; 2 4 4 6; 3 6 6 9]
EDIT2:
For an arbitrary number of x's in m...
n = 3; % number of repetitions...
x = [1 2 2 3];
m = [];
for i=1:n
m = [m;x];
end