2

I'm quite new to programming so am looking for some experts to nudge me in the right direction as I complete this exercise.

I have used horzcat and vertcat to manually do this but I'm asking if anyone knows a simpler way.

Matrix 1 is 18x18 and indexed horizontally starting at 1.

Matrix 1 is at the centre and represents a discrete space. Matrix 2,3,4,5,6,7,8,9 are replicates of matrix 1, also represent discrete spaces and are located right, lower right, below, lower left, left, top left, above and top right.

Matrix 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 are also replicates of matrix one and surround Matrix 2 to 9. The matrices built together form a pattern as below. Each matrix is itself a discrete unit.

If you define the number of matrices you require, so let's say in this case '49' or '4 steps from matrix 1' (a person can jump from 1, 9, 25, 49 on a diagonal or 1, 8, 23,46 on a straight line), how do I build the matrices in this pattern?

                      43  44  45  46 47  48 49
                      42  21  22  23 24  25 26
                      41  20  7   8   9  10 27
                      40  19  6   1   2  11 28
                      39  18  5   4   3  12 29
                      38  17  16  15  14 13 30
                      37  36  35  34  33 32 31     

If I demonstrate this diagrammatically, I hope I can express my problem better.

So the first ring is this:

                               7 8 9
                               6 1 2
                               5 4 3

the second ring is this:

                       21  22  23  24  25
                       20  7   8   9   10
                       19  6   1   2   11
                       18  5   4   3   12
                       17  16  15  14  13

the third ring is

                  43  44  45  46  47  48  49
                  42  21  22  23  24  25  26
                  41  20   7   8   9  10  27
                  40  19   6   1   2  11  28
                  39  18   5   4   3  12  29
                  38  17  16  15  14  13  30
                  37  36  35  34  33  32  31

and so on. I'd like to be able to continue this pattern infinitely.

What is the best way to do this in Matlab?

I apologise for my lack of clarity and need to express my problem better. All your comments are very useful in showing me how to write a proper problem.

Many thanks for your help guys. Just joined this forum as the support here is exceptional.

Amro
  • 123,847
  • 25
  • 243
  • 454
Tetra
  • 747
  • 2
  • 9
  • 15
  • 1
    ... not clear what you want. "Add spaces"? "Another 8 matrices", do you mean "8 matrix elements"? What doubles? What do you mean by layer? ... – Jonas Heidelberg Oct 20 '11 at 11:56
  • Sorry, I'm finding this very difficult to explain. Each matrix represents a space. I want to add replicates of one matrix in concentric rings. So, matrix 1 is 18x18. Matrix 2, 3, 4, 5, 6, 7, 8, 9 are replicates of matrix 1 but are located right, lower right, below, lower left, left, upper left, upper, upper right. The doubling is that if 1 is in the centre, there are 8 surrounding the 1 and then 16 surrounding the 8 and so on. – Tetra Oct 20 '11 at 12:38
  • Maybe you can use the "edit" link below your question to improve your text, and incorporate what you say in the comment? – Jonas Heidelberg Oct 20 '11 at 13:03
  • "Doubling" is a bit weird here because the number of submatrices you have increases 1->9->25->49->81, so the number you add is 8,16,24,32... so nothing is doubling if you understand you correctly – Jonas Heidelberg Oct 20 '11 at 13:08
  • Sorry I explained this poorly. The doubling was just 8 to 16. The pattern is indeed 1 8 16 24 32. I've added a better explanation. Thank you for your comments! They're very helpful! – Tetra Oct 20 '11 at 13:34
  • You say "I have used horzcat and vertcat to manually" - please post that code in your question so we see what you are trying to achieve. – Jonas Heidelberg Oct 20 '11 at 13:41

2 Answers2

2

If all your matrices are truly copies ("replicates") of the initial one (call it mat18), for your nth step you could just call

largemat=repmat(mat18, 2*n+1, 2*n+1);

e.g.

largemat=repmat(mat18, 7,7);

to produce the matrix you described in your example. As Clement says, this creates the large matrix directly, not by expanding an existing one.

Update 2

If your matrices are different, for example you have 49 matrices stored in a cell array mymatrices{1}, mymatrices{2}, ... mymatrices{49}, you would start by

largemat{1}=mymatrices{1};

Now to calculate the next largemat{n+1} from mymatrices and largemat{n}, you need to add the next mymatrices "around" the largemat{n}. largemat{n} already contains the first m^2 matrices with m=2*n+1, so you will need mymatrices{(m^2+1):((m+2)^2)} and arrange them correctly:

and then in each step enlarge it

largemat{n+1} = [ largemat{n} cell2mat(mymatrices(m^2+(1:m))')]; %# add to the right
largemat{n+1} = [ largemat{n+1} ; cell2mat(mymatrices(m^2+m+(m+1:-1:1)))]; %# add at bottom
largemat{n+1} = [ cell2mat(mymatrices(m^2+2*m+1+(m+1:-1:1))') largemat{n+1}]; %# add at right
largemat{n+1} = [ cell2mat(mymatrices(m^2+3*m+2+(1:m+2))) ; largemat{n+1}]; %# add at top

To test this code, lets use simple numbers for your submatrices:

mymatrices=mat2cell(1:49,1,ones(1,49));

Now we can run the above code in a loop, printing intermediate results to check:

largemat{1}=mymatrices{1};
for n=1:3
    m=2*n-1;
    largemat{n+1} = [ largemat{n} cell2mat(mymatrices(m^2+(1:m))')]; %# add to the right
    largemat{n+1} = [ largemat{n+1} ; cell2mat(mymatrices(m^2+m+(m+1:-1:1)))]; %# add at bottom
    largemat{n+1} = [ cell2mat(mymatrices(m^2+2*m+1+(m+1:-1:1))') largemat{n+1}]; %# add at right
    largemat{n+1} = [ cell2mat(mymatrices(m^2+3*m+2+(1:m+2))) ; largemat{n+1}]; %# add at top
    largemat{n+1}
end

which prints

ans =
     7     8     9
     6     1     2
     5     4     3
ans =
    21    22    23    24    25
    20     7     8     9    10
    19     6     1     2    11
    18     5     4     3    12
    17    16    15    14    13
ans =
    43    44    45    46    47    48    49
    42    21    22    23    24    25    26
    41    20     7     8     9    10    27
    40    19     6     1     2    11    28
    39    18     5     4     3    12    29
    38    17    16    15    14    13    30
    37    36    35    34    33    32    31

To test it also works for nonscalar input matrices, use

mymatrices=cell(1,49);
for i=1:49,mymatrices{i}=rand(9,9),end;

as input, which doesn't crash... even though I haven't checked manually that the resulting matrix is correct ;-).

Jonas Heidelberg
  • 4,984
  • 1
  • 27
  • 41
  • Can't thank you enough. I'm trying out your code in the meantime. – Tetra Oct 20 '11 at 14:44
  • @BD020: I just posted a corrected version - note the use of `cell2mat` which I had forgotten previously! – Jonas Heidelberg Oct 20 '11 at 14:49
  • Experimenting further! If each cell up there was a vector, could I shift values from one vector to another? Can I shift 5% of each vector's row value to all other vector rows to only the matrices surrounding the one I specify (e.g. If I specify 1, 2 to 9 vectors recieve 5% of the total of vector 1.) So row one of vector one moves into row one of vector two,three etc. What method would you recommend? I am doing it manually at the moment. Many thanks for your time! (Should I reask this as a q?) – Tetra Oct 22 '11 at 23:52
  • This is definitely a new question; make sure to link from the new question to this one! Try to explain it well, maybe explaining things twice with different words, and giving a small example! – Jonas Heidelberg Oct 22 '11 at 23:54
1

It's probably simpler to write a function that generate all your matrix for a given number of layers instead of trying to expand an existing matrix with a new layer.

Clement J.
  • 3,012
  • 26
  • 29