# How to find the boundary elements of a matrix?

Consider a matrix m as

m = RandomInteger[10, {10, 10}];


In the matrix form this is (in my case)

Now I want to extract the boundary elements of this matrix at different levels as shown in different colors in the following image

How can I do this?

If the matrix is called A and if k is the depth then

Join[
A[[k, k ;; -(k + 1)]],
A[[k ;; -(k + 1), -k]],
A[[-k, -k ;; k + 1 ;; -1]],
A[[-k ;; k + 1 ;; -1, k]]
]


should provide you with the elements, starting in the top left in clockwise order.

Just for fun, here's a different solution:

pos[m_, {l1_, l2_}, dim_] := Position[
CenterArray[ArrayPad[ConstantArray[1, {l1, l2}], 1], dim, 1],
0
]


We can now specify any border using l1 and l2:

MapAt[Style[#, Red] &, m, pos[m, {2, 4}, Dimensions[m]]] // MatrixForm


The {2, 4} denotes the dimension of the matrix inside the selected border. It has two rows and four columns.

This retrieves the elements:

Extract[m, pos[m, {2, 4}, Dimensions[m]]]

• It would be great if the elements can be retrieved in a cyclic order. For example, in the given case your code returns 7,4,10,6,7,1,1,1,6,3,8,0,4,6,2,7. What I want is: 1,1,7,6,10,4,7,1,6,8,0,4,6,2,7 - starting from central right (1) and move anticlockwise. Feb 15 '18 at 12:51
ClearAll[layerF, layerindicesF]
layerF[dims : {_, _}, {r_, c_}] := Module[{m = Array[1 &, dims]},
ArrayPad[ArrayPad[m, {{-r + 1}, {-c + 1}}], {{r - 1}, {c - 1}}] -
layerF[dims : {_, _}, r_Integer] := layerF[dims, {r, r}]
layerindicesF[dims : {_, _}, rc_] := Position[layerF[dims, rc], 1]


Examples:

layerF[{10, 10}, {2, 3}] /. 1 -> Style[1, 20, Red] // MatrixForm


layerindicesF[{10, 10}, 3]


{{3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, {4, 3}, {4, 8}, {5, 3}, {5, 8}, {6, 3}, {6, 8}, {7, 3}, {7, 8}, {8, 3}, {8, 4}, {8, 5}, {8, 6}, {8, 7}, {8, 8}}

SeedRandom[1]
m = RandomInteger[10, {10, 10}];
Extract[m, layerindicesF[{10, 10}, 3]]


{2, 6, 4, 5, 4, 3, 3, 9, 3, 4, 9, 10, 2, 1, 8, 6, 5, 6, 0, 10}

Grid[m, Background -> {None, None,
Join @@ (Thread[layerindicesF[{10, 10}, #] -> {Red, Orange, Yellow, Pink,
LightRed}[[#]]] & /@ Range[5])}, ItemSize -> {2, 2},
Dividers -> All, ItemStyle -> Directive[20, Bold]]


Row[{MatrixForm[m], MatrixForm @ MapAt[Style[#, Red, Bold, 20] &,
m layerF[Dimensions[m], 3], layerindicesF[Dimensions[m], 3]],
MatrixForm @ MapAt[Style[#, Red, Bold, 20] &, m, layerindicesF[Dimensions[m], 3]]},
Spacer[5]]


Row[MatrixForm @ MapAt[Style[#, Red, Bold, 20] &, m layerF[Dimensions[m], #],
layerindicesF[Dimensions[m], #]] & /@ {{2, 4}, {1, 3}, {3, 2}}, Spacer[5]]


Note: C.E.'s method using CenterArray is much more elegant. However, it is available only in versions v11+. The method above works in version 9.