2

I have a matrix (with the size of A and B; suppose 100x100) and want to fill in with smaller matrix (or block) with the size of a and b (suppose 12x12). But, when I use the following loop, the edge of matrix cannot be filled and will be empty. One solution is to use a large matrix (e.g. 120x120) and fill with the smaller blocks and then finally crop the final matrix to 100x100. But, I do not want to use this solution. Instead, I would like to back the edge matrix and use the same axb block. In other words, when I reach the edges, I want to back with the size of block on that direction and fill the remained part.

I am totally confused that how I should include this idea in my matlab codes. any idea?

M = zeros(100,100);

for i = 1:12:100-12+1
    for j = 1:12:100-12+1
        block = rand(12,12);
        M(i:i+11, j:j+11) = block;
    end;
end;

figure, imagesc(M); axis equal tight xy
Sam
  • 939
  • 5
  • 14
  • 41
  • 1
    Well, C++'s looping constructs don't have a strong, in-built notion of step size like Matlab's. So, how you solve the problem in one language vs. another will be somewhat different. – Joe Z Dec 15 '13 at 18:19
  • Your problem is unclear. Are all small the same, or only the same size? Where is the index (1,1)? Bottom left? You have overlapping blocks, what should be done in the overlapping areas? Overwrite? Add? – Daniel Dec 15 '13 at 18:26
  • Yes, all small blocks have the size of 12x12 and index (1,1) is located in left-bottom. Finally I want to overwrite the new blocks in the edges (overwrite the red block with previous black blocks) – Sam Dec 15 '13 at 18:29
  • In which kind of data structure are the block arranged, if not all blocks are the same? – Daniel Dec 15 '13 at 18:30
  • all blocks are the same size of 12x12 (just some random numbers; I think their values are not important) – Sam Dec 15 '13 at 18:31
  • @Sam Daniel's question was about the data structure of those blocks. For example, do all blocks form a 3D matrix? – Luis Mendo Dec 15 '13 at 19:00

2 Answers2

1

It's best not to use i and j as variable names in Matlab. I'm changing to ii and jj.

What you should do is: choose the indices i and j as follows:

for ii = [1:12:100-12, 100-12+1]

or in general

for ii = [1:step_size_x:matrix_size_x-step_size_x, matrix_size_x-step_size_x+1]

and similarly for jj:

for jj = [1:step_size_y:matrix_size_y-step_size_y, matrix_size_y-step_size_y+1]

This works by treating the special index separately and appending it at the end.

Community
  • 1
  • 1
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
0

I think the following works: letC = A div a, D = B div b (where div is for integer division). Then, using repmat (much faster than for loops), assign the CxD tiling of block as the bottom left part of M. Then, create (again, probably using repmat, e.g., repmat(block,C+1,1)), create C+1 x 1 and 1 x D+1 blocks of tiles, crop them appropriately (so that they fit into A,B) and assign these as the top "row of blocks" and rightmost "column of blocks" of M (which will overwrite some of the formerly assigned values, which is, I believe, what you want).

TJ27
  • 308
  • 1
  • 7
  • Thanks Jakubb. But, I did not get your point and answer. Can you please make it a little clear? as I mentioned, I don't want to use a larger matrix and then crop it. So, your solution tends to use a larger matrix, is not it? – Sam Dec 15 '13 at 19:08
  • Not really. You start with preallocating matrix AxB. I suggest, you produce the following: 1) M*a x N*b matrix which you put as a bottom left submatrix of the AxB matrix. Since M*a<=A and N*b – TJ27 Dec 15 '13 at 21:34
  • but it will be a bit more code - still, essentially quite a simple code. – TJ27 Dec 15 '13 at 21:39