4

I need some help in converting a 2X2 matrix to a 4X4 matrix in the following manner:

A = [2 6;
     8 4]

should become:

B = [2 2 6 6;
     2 2 6 6;
     8 8 4 4;
     8 8 4 4]

How would I do this?

Amro
  • 123,847
  • 25
  • 243
  • 454
anubhav
  • 643
  • 3
  • 9
  • 19

7 Answers7

23

In newer versions of MATLAB (R2015a and later) the easiest way to do this is using the repelem function:

B = repelem(A, 2, 2);

For older versions, a short alternative to the other (largely) indexing-based solutions is to use the functions kron and ones:

>> A = [2 6; 8 4];
>> B = kron(A, ones(2))

B =

     2     2     6     6
     2     2     6     6
     8     8     4     4
     8     8     4     4
gnovice
  • 125,304
  • 15
  • 256
  • 359
  • shorter, although for generalization to large matrices, there's unnecessary multiplication that may slow things down. – Jason S Oct 29 '09 at 14:17
  • @Jason S: True, but for larger matrices you would also have to do quite a bit more work in generating the indices needed by the other solutions here. – gnovice Oct 29 '09 at 14:26
12

Can be done even easier than Jason's solution:

B = A([1 1 2 2], :);  % replicate the rows
B = B(:, [1 1 2 2]);  % replicate the columns
Shai
  • 111,146
  • 38
  • 238
  • 371
Martijn
  • 5,471
  • 4
  • 37
  • 50
9

Here's one more solution:

A = [2 6; 8 4];
B = A( ceil( 0.5:0.5:end ), ceil( 0.5:0.5:end ) );

which uses indexing to do everything and doesn't rely on the size or shape of A.

Edric
  • 23,676
  • 2
  • 38
  • 40
4

This works:

A = [2 6; 8 4];
[X,Y] = meshgrid(1:2);
[XI,YI] = meshgrid(0.5:0.5:2);
B = interp2(X,Y,A,XI,YI,'nearest');

This is just two-dimensional nearest-neighbor interpolation of A(x,y) from x,y ∈ {1,2} to x,y ∈ {0.5, 1, 1.5, 2}.

Edit: Springboarding off of Jason S and Martijn's solutions, I think this is probably the shortest and clearest solution:

A = [2 6; 8 4];
B = A([1 1 2 2], [1 1 2 2]);
las3rjock
  • 8,612
  • 1
  • 31
  • 33
2
A = [2 6; 8 4];
% arbitrary 2x2 input matrix

B = repmat(A,2,2);
% replicates rows & columns but not in the way you want

B = B([1 3 2 4], :);
% swaps rows 2 and 3

B = B(:, [1 3 2 4]);
% swaps columns 2 and 3, and you're done!
Jason S
  • 184,598
  • 164
  • 608
  • 970
  • Nice! I thought there should be some way to do this with repmat and column and row swapping, but my brain is still half-asleep. – las3rjock Oct 29 '09 at 13:42
  • Solution by gnovice using Kroneker KRON function is better - it is more straightforward and clear - "intentional programming" – Mikhail Poda Oct 30 '09 at 07:55
  • I like Martijn's answer better but that's just me. – Jason S Oct 30 '09 at 13:06
  • With respect to all the indexing-based solutions, I actually prefer Edric's (which is a generalized form of las3rjock's edit). – gnovice Oct 30 '09 at 15:33
  • The mathematical operation in question is called "Kronecker product" http://en.wikipedia.org/wiki/Kronecker_product. The solution by gnovice does exactly this, directly. Other solutions, whatsoever clever, are detours. – Mikhail Poda Oct 30 '09 at 17:56
  • Kronecker product is more general and allows multiplication. OP wanted to replicate matrix elements to form a block matrix. KRON function documentation, IMHO, is confusing and its use is less clear for this purpose. But we can agree to disagree. – Jason S Oct 30 '09 at 19:54
2

Here's a method based on simple indexing that works for an arbitrary matrix. We want each element to be expanded to an MxN submatrix:

A(repmat(1:end,[M 1]),repmat(1:end,[N 1]))

Example:

>> A=reshape(1:6,[2,3])

A =

     1     3     5
     2     4     6

>> A(repmat(1:end,[3 1]),repmat(1:end,[4 1]))

ans =

     1     1     1     1     3     3     3     3     5     5     5     5
     1     1     1     1     3     3     3     3     5     5     5     5
     1     1     1     1     3     3     3     3     5     5     5     5
     2     2     2     2     4     4     4     4     6     6     6     6
     2     2     2     2     4     4     4     4     6     6     6     6
     2     2     2     2     4     4     4     4     6     6     6     6

To see how the method works, let's take a closer look at the indexing. We start with a simple row vector of consecutive numbers

>> m=3; 1:m

ans =

     1     2     3

Next, we extend it to a matrix, by repeating it M times in the first dimension

>> M=4; I=repmat(1:m,[M 1])

I =

     1     2     3
     1     2     3
     1     2     3
     1     2     3

If we use a matrix to index an array, then the matrix elements are used consecutively in the standard Matlab order:

>> I(:)

ans =

     1
     1
     1
     1
     2
     2
     2
     2
     3
     3
     3
     3

Finally, when indexing an array, the 'end' keyword evaluates to the size of the array in the corresponding dimension. As a result, in the example the following are equivalent:

>> A(repmat(1:end,[3 1]),repmat(1:end,[4 1]))
>> A(repmat(1:2,[3 1]),repmat(1:3,[4 1]))
>> A(repmat([1 2],[3 1]),repmat([1 2 3],[4 1]))
>> A([1 2;1 2;1 2],[1 2 3;1 2 3;1 2 3;1 2 3])
>> A([1 1 1 2 2 2],[1 1 1 1 2 2 2 2 3 3 3 3])
Wil Koenen
  • 21
  • 2
-4

There is a Reshape() function that allows you to do this...

For example:

reshape(array, [64, 16])

And you can find a great video tutorial here

Cheers

Anthony M. Powers
  • 1,257
  • 9
  • 10
  • 1
    reshape will not work for this--it requires that the input and output matrices have the same number of elements. – las3rjock Oct 29 '09 at 13:06
  • thanks for a quick one but i think for reshape the number of elements must not change. Here i have a 2X2 matrix ie 4 elements and i want to make a 4X4 matrix so 16 elements.No of elements are different. Wat to do? – anubhav Oct 29 '09 at 13:07
  • Are you desiring the 'Reshape' process to add relevant element data in the newly-created space? – Anthony M. Powers Oct 29 '09 at 13:56