# Put edges of a matrix to zero

I have to set the first and last rows and columns to zero rows and columns.

I tried with the first column:

For[a = 1, a <= 3, a++, M = ReplacePart[mat, {a, 1} -> 0]; Print[M]]


{{0,1,1},{1,1,1},{1,1,1}

{{1,1,1},{0,1,1},{1,1,1}}

{{1,1,1},{1,1,1},{0,1,1}}

How can I solve this?

• Please, read the full documentation on ReplacePart. Also, it's good practice to include self contained examples -- in this case your initialisation of mat is missing. Commented May 24, 2018 at 11:21

array  = ArrayReshape[Range[5 7], {5, 7}];
Fold[ArrayPad, array, {-1, 1}] // MatrixForm // TeXForm


$\left( \begin{array}{ccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 9 & 10 & 11 & 12 & 13 & 0 \\ 0 & 16 & 17 & 18 & 19 & 20 & 0 \\ 0 & 23 & 24 & 25 & 26 & 27 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

Also

ArrayPad[ArrayPad[array, -1], 1]
ArrayPad[array[[2 ;; -2, 2 ;; -2]], 1]
array (1 - MorphologicalPerimeter[array])
MapAt[0 &, array, {{All, {1, -1}}, {{1, -1}, All}}]
ReplacePart[array, {1 | Dimensions[array][[1]], _} | {_, 1 | Dimensions[array][[2]]} :> 0]


all give the same result.

• Henrik brought up an important issue on array (un)packing, please see my comment below his answer. Commented May 24, 2018 at 12:17
• Thank you @LLlAMnYP.
– kglr
Commented May 24, 2018 at 12:19
m = 2000;
n = 1000;
mat = RandomReal[{-1, 1}, {m, n}];

First@RepeatedTiming[

M = mat;
M[[{1, -1}, All]] = 0.;
M[[2 ;; -2, {1, -1}]] = 0.;

]


0.0039

• Your method doesn't unpack array because you set the elements to real 0.. If you modify kglr's solution to Fold[ArrayPad[##, 0.] &, array, {-1, 1}], it also doesn't unpack. Commented May 24, 2018 at 12:16
• Yeah, I've just observed that and deleted that remark. It's still about three times faster. Commented May 24, 2018 at 12:18
a = Array[1 &, {5, 7}];


Border positions

p = {{All, 1}, {All, -1}, {1, All}, {-1, All}};


Using ReplaceAt (new in 13.1)

ReplaceAt[a, _ :> 0, p] // MatrixForm


Just another way and @kglr example:

zero[mat_] := Module[{d = Dimensions[mat]},
ArrayPad[ConstantArray[1, d - {2, 2}], 1] mat]
array = ArrayReshape[Range[5  7], {5, 7}];
MatrixForm /@ (array -> zero[array])


Using timing example:

m = 2000;
n = 1000;
mat = RandomReal[{-1, 1}, {m, n}];
First[RepeatedTiming[zero[mat]]]


gives: 0.00985614

array = ArrayReshape[Range[5 17], {5, 17}];  // after kglr

Transpose[Transpose[array.DiagonalMatrix[{0, 1, 1, 1, 1, 1, 0}]].DiagonalMatrix[{0, 1,
1, 1, 0}]] // MatrixForm


Or, more generally:

array // Transpose[Transpose[#.SparseArray[{{1, 1} -> 0,
ConstantArray[Dimensions[#][[2]], 2] -> 0, Band[{1, 1}] -> 1},
Dimensions[#][[2]]]].SparseArray[{{1, 1} -> 0,
ConstantArray[Dimensions[#][[1]], 2] -> 0, Band[{1, 1}] -> 1},
Dimensions[#][[1]]]] & // MatrixForm


$\left( \begin{array}{ccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 9 & 10 & 11 & 12 & 13 & 0 \\ 0 & 16 & 17 & 18 & 19 & 20 & 0 \\ 0 & 23 & 24 & 25 & 26 & 27 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

A variant using BoxMatrix

array = ArrayReshape[Range[5  7], {5, 7}]; (*kglr's example*)
array BoxMatrix[.5 (# - 3), #] &@Dimensions@array // MatrixForm
`

$$\left( \begin{array}{ccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 9 & 10 & 11 & 12 & 13 & 0 \\ 0 & 16 & 17 & 18 & 19 & 20 & 0 \\ 0 & 23 & 24 & 25 & 26 & 27 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$$