Quick way to replicating old matrix to new one - matlab

e.g I have the original matrix (m) looks like this one
1 2
3 4
Then I use n = padarray(m,[oldMatrixRow,OldMatrixColumn]); I will have
x x x x x x
x x x x x x
x x 1 2 x x
x x 3 4 x x
x x x x x x
x x x x x x
The point here is that I would want my new matrix look like this
1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
Is there any smart way to do that ?
Thank you very much

You want repmat
B = repmat(A,m,n)
where A is the matrix you want to repeat, and m and n define the dimensions of how it is repeated
In your case here, call your original matrix A and use
B = repmat(A,3,3)
to get your desired output

Assuming you just want to repeat your matrix a number of times the easy way would be to use repmat:
m = [1 2;3 4];
n = repmat(m,3,3)

Just to give an alternative solution:
kron(ones(3), [1 2; 3 4])

Related

Creating a matrix according to some rules

How can I generate the following matrix having m rows and n columns?
1st row 1 2 3 L n-1 n
2nd 2 3 4 L n 1
3rd 3 4 5 n-1 1 2
Nth M M M ....
N-1 m-1 m m+1 L m-3 m-2
last m m+1 m+2 l m-2 m-1
It's difficult to tell from your description, but it appears you want to create a matrix where the first row is 1:n and each successive row is a circular shift to the left of the previous row. If so, you can still use hankel for this (as Dev-iL mentions in their answer), but incorporate a remainder operation like so:
n = 5;
m = 8;
mat = rem(hankel(0:(m-1), (m-1):(m+n-2)), n)+1
mat =
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
This looks like a Hankel matrix. You should use the 2-input syntax for it,
H = hankel(c,r)
So for example, with m = 4 and n = 5 we get:
m = 4; n = 5;
X = hankel( 1:m, m:m+n-1 )
X =
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

Symmetrically extending a matrix

How can I extend a matrix in MATLAB by symmetrically replicating the boundary values? For example, if X is my matrix, extended matrix Xextsym should look like the following:
X =
1 2 3
4 5 6
Xextsym =
5 4 4 5 6 6 5
2 1 1 2 3 3 2
2 1 1 2 3 3 2
5 4 4 5 6 6 5
5 4 4 5 6 6 5
2 1 1 2 3 3 2
I'm aware that a function called wextend exists in the Wavelet Toolbox for this task exactly, but I don't have it.
Here is a function that extends a given matrix A by symmetric reflection, adding w element in each of four directions. Usage example:
symextend([1 2 3; 4 5 6], 2)
returns the extended matrix in your question.
function R = symextend(A, w)
[m, n] = size(A);
B = [A A(:, n:-1:1); A(m:-1:1, :) A(m:-1:1, n:-1:1)];
repm = 2*ceil(0.5+0.5*w/m);
repn = 2*ceil(0.5+0.5*w/n);
C = repmat(B, repm, repn);
R = C(m*repm + 1 - w : m*repm + m + w, n*repn + 1 - w : n*repn + n + w)
end
Idea: first reflect A once in each direction (this produces B), then repeat B with repmat, obtaining C. Finally, a suitable piece is carved out of C. The tricky parts are counting how many times to repeat, and which part to carve out.

Build a huge matrix with vector components in MATLAB

How can I avoid using a double for loop in order to build a matrix pos like this code does:
pos=[0 0];
for i=1:m;
for j=1:n;
pos=[pos; i j];
end
end
m and n are numbers such as 500 and 900.
I have to find a better solution in order improve computation time.
Thank you so much.
You can easily do this by meshgrid.
[X,Y] = meshgrid(1:m, 1:n);
pos = [0 0; X(:) Y(:)];
How the above code works is the following. meshgrid (in this case) creates a 2D grid of (X,Y) co-ordinates. X progresses horizontally while Y progresses vertically. As we can see in your for loops, m defines the horizontal boundaries while n denotes the vertical boundaries. By calling meshgrid(1:m, 1:n), I am creating a n x m grid for both X and Y, where each row of X progresses from 1 to m, while each column of Y progresses from 1 to n. Therefore, these will both be n x m matrices. Calling the above with m = 4 and n = 5 computes:
m = 4;
n = 5;
[X,Y] = meshgrid(1:m, 1:n)
X =
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
Y =
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
This almost follows the format you wish. You'll notice that by looking at the columns individually, this achieves what you want, but you want to stack all of the X and Y to be in a (n x m) + 1 x 2 matrix (1 to account for [0 0]). All we have to do now is take every column of X and Y and stack them on top of each other to create a single column for both. We can stack all of these together by doing X(:) and Y(:). X(:) will take every column of X and create a single column that stacks all of the columns together. The same is done for Y(:). As such, we first create pos by attaching [0 0] as the first row, and we then attach X(:) and Y(:) as columns to pos after, thus completing the construction of pos.
Let's do an example as a proof-of-concept. Suppose that we use the same values like we did before:
m = 4;
n = 5;
Using your for loop, we get:
pos =
0 0
1 1
1 2
1 3
1 4
1 5
2 1
2 2
2 3
2 4
2 5
3 1
3 2
3 3
3 4
3 5
4 1
4 2
4 3
4 4
4 5
Using the code I have written, we also get:
pos =
0 0
1 1
1 2
1 3
1 4
1 5
2 1
2 2
2 3
2 4
2 5
3 1
3 2
3 3
3 4
3 5
4 1
4 2
4 3
4 4
4 5
Minor Note
As you stated that m and n are going to be relatively large, I would recommend you clear X and Y from your workspace before you proceed. X and Y were only created to help you create pos. As you don't need them anymore, after you calculate pos, do:
clear X;
clear Y;

Create matrix in Matlab enumerating coordinates

Is there an efficient way (e.g., without using for loops manually) to create a matrix in Matlab that enumerates the 2-D coordinates of a matrix of a given size?
For example, if I'm given an m x n matrix, I want the resulting mn x 2 matrix to be as follows:
1 1
1 2
1 3
...
1 n
2 1
2 2
...
m 1
m 2
...
m n
Thanks in advance!
mat = [1 2;3 4;5 6;7 8;9 10];
[m,n] = size(mat);
vec = [kron(1:m,ones(1,n)); kron(ones(1,m),1:n)]'
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2
Robert P. has a correct (and elegant) answer with a nifty use of kron, but just for fun here's the alternative with ndgrid,
>> mat=zeros(5,2);
>> [nn,mm] = ndgrid(1:size(mat,2),1:size(mat,1))
>> vec = [mm(:) nn(:)]
vec =
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2

How to perform this kind of matrix division in Matlab?

This problem is probably less to do with Matlab and more to do with matrix algebra (which I mostly forget from my college courses). Say I have a m x n matrix X and a m x 1 matrix B. How would I divide the X by B such that all the elements of the ith row of X are piecewise divided by the ith row of B, resulting in another m x n matrix Y?
E.g.
X = [2 4 8; 3 9 27; 4 16 64]
B = [2; 3; 4]
X ? B = [2/2 4/2 8/2; 3/3 9/3 27/3; 4/4 16/4 64/4]
ans =
1 2 4
1 3 9
1 4 16
Better not use repmat - it is slow and allocates additional memory for the workspace. You can use bsxfun, which is an inbuilt function, so it is faster and avoids the extra workspace:
X = [2 4 8; 3 9 27; 4 16 64]
B = [2; 3; 4]
bsxfun(#rdivide, X, B)
ans =
1 2 4
1 3 9
1 4 16
Junuxx's comment pointed me in the right direction. The solution I used to get what I wanted is:
B_prime = repmat(B,1,3)
X ./ B_prime
ans =
1 2 4
1 3 9
1 4 16
I'd still like to know what this kind of operation is called (if it even has a formal name).
X is m x n and B is m x 1
size(X,2) gives the value of n i.e. number of columns
So, you need to do:
X./repmat(B,1,size(X,2))
X = [2 4 8; 3 9 27; 4 16 64]
B = [2; 3; 4]
Result= X./B(:,ones(1,3)) %is faster then repmat
Result =
1 2 4
1 3 9
1 4 16