0
$\begingroup$

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.

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

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}]
|improve this answer|||||
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.