# Conditionally replace element value to 0. in blocks of small matrice

I have a matrix that can be split into some small blocks. I want to set the value of elements to 0. if their original value greater than 1.

I have implemented the replacements by :

a = RandomReal[1.5, {15, 15}];
b = Clip[a, {0., 1.}, {0., 0.}]


Now I want to further add the condition: If one element is replaced by 0. in a 3*3 block, all those 3*3 = 9 elements are going to be set to 0. as well.

For example, In my original matrix with dimension 15*15, it could be seperate into 25 small blocks with dimension3*3, if the below 3*3 block was one of them. I hope to set all elements to 0. because there is a 0 on the last row. And doing the same operation to other small blocks if the condition satisfied.

{{0.460116, 0.870853, 0.206321},
{0.864099, 0.539186, 0.93472},
{0.78918, 0., 0.382635}}


Note: in the original matrix, there is no 0. occurs, so when I see there is a 0 in b,I know it'd been replaced already.

I am having the feeling that maybe SparseArray could solve the problem, but it will generate unpacked arrays which I am trying to avoid. So I appreciate your thoughts about my problem.

• ArrayFlatten@BlockMap[If[Min[#] == 0, 0 #, #] &, b, {3, 3}]? – kglr Dec 24 '18 at 3:12
• No need to create b. ArrayFlatten@BlockMap[If[Max[#]>1, 0 #, #] &, a, {3, 3}] – OkkesDulgerci Dec 24 '18 at 3:49

There might be more elegant way.

 SeedRandom@2;
a = RandomReal[1.1, {15, 15}];
b = Clip[a, {0, 1}, {0, 0}];

subset = Join @@
Table[b[[i ;; i + 2, j ;; j + 2]], {i, 1, 15, 3}, {j, 1, 15, 3}];

MatrixForm /@
Table[If[MemberQ[Flatten@subset[[i]], 0.] == True,
subset[[i]] = 0 subset[[i]], subset[[i]]], {i, Length@subset}]


Or

MatrixForm /@
Table[If[Min@subset[[i]] == 0, subset[[i]] = 0 subset[[i]],
subset[[i]]], {i, Length@subset}]


Or no need to create b.

subset = Join @@
Table[a[[i ;; i + 2, j ;; j + 2]], {i, 1, 15, 3}, {j, 1, 15, 3}];

ArrayFlatten@
Partition[
Table[If[Max@subset[[i]] > 1, subset[[i]] = 0 subset[[i]],
subset[[i]]], {i, Length@subset}], 5]


I suggest @kglr solution:

ArrayFlatten@BlockMap[If[Max[#]>1, 0 #, #] &, a, {3, 3}]