4

Assuming I have the a 5x7 matrix below: b = ((1, 4, 9, 16, 25, 4, 2), (36, 49, 64, 81, 100, 5, 1), (121, 144, 169, 196, 225, 8, 9), (256, 289, 324, 361, 400, 9, 5), (441, 484, 529, 576, 625, 3, 7)) I want to set some elements on each row and different column to zero. such that, I will have: b[[(Row1, column 2;;3 and column 5;;7),(Row2, column 1;;2 and column 4;;7),(Row3, column 1;;4 and column 6;;7),(Row4, column 2;;3 and column 6;;7),(Row5, column 1;;4 and column 6;;7)]]=0

kglr
  • 394,356
  • 18
  • 477
  • 896
Geop
  • 87
  • 3
  • duplicate of https://mathematica.stackexchange.com/questions/191658/elements-replacement – Roman Feb 17 '19 at 11:13
  • 2
    When posting questions use proper Mathematica syntax. For example, in the example definition of b, you should have used List brackets rather than parentheses. This would help others help you, since they could then copy and paste the data into a notebook without having to manually edit it. – Bob Hanlon Feb 17 '19 at 14:13

1 Answers1

5
b = {{1, 4, 9, 16, 25, 4, 2}, {36, 49, 64, 81, 100, 5, 1}, {121, 144, 169, 196, 225, 8, 9}, 
    {256, 289, 324, 361, 400, 9, 5}, {441, 484, 529, 576, 625, 3, 7}};
cols = {{2 ;; 3, 5 ;; 7}, {1 ;; 2, 4 ;; 7}, {1 ;; 4, 6 ;; 7}, 
    {2 ;; 3, 6 ;; 7}, {1 ;; 4, 6 ;; 7}};

You can use MapAt:

pos = MapIndexed[Thread[{#2[[1]], #}] &, cols];

b2 = MapAt[0 &, b, Join @@ pos];
TeXForm[Row[MatrixForm /@ {b, b2}]]

$\left( \begin{array}{ccccccc} 1 & 4 & 9 & 16 & 25 & 4 & 2 \\ 36 & 49 & 64 & 81 & 100 & 5 & 1 \\ 121 & 144 & 169 & 196 & 225 & 8 & 9 \\ 256 & 289 & 324 & 361 & 400 & 9 & 5 \\ 441 & 484 & 529 & 576 & 625 & 3 & 7 \\ \end{array} \right)\left( \begin{array}{ccccccc} 1 & 0 & 0 & 16 & 0 & 0 & 0 \\ 0 & 0 & 64 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 225 & 0 & 0 \\ 256 & 0 & 0 & 361 & 400 & 0 & 0 \\ 0 & 0 & 0 & 0 & 625 & 0 & 0 \\ \end{array} \right)$

Alternatively, you can use SparseArray:

keep = Join @@ MapIndexed[Thread[{#2[[1]], #}] &, 
   Complement[Range@Dimensions[b][[2]], #] & /@ Join @@@ (cols /. Span -> Range)]

b3 = SparseArray[keep -> Extract[b, keep], Dimensions[b]];

or ReplacePart:

inds = Join @@ MapIndexed[Thread[{#2[[1]], #}] &, Join @@@ (cols /. Span -> Range)];
b4 = ReplacePart[b, inds -> 0]

or Part assignment inside Do or Table or MapIndexed:

b5 = b;
Do[b5[[## & @@ i]] = 0, {i, inds}]

b6 = b;
Table[b6[[## & @@ i]] = 0, {i, inds}];

cols2 = Join @@@ (cols /. Span -> Range);
b7 = b;
MapIndexed[(b7[[#2[[1]], #]] = 0) &, cols2];

b2 == b3 == b4 == b5 == b6 == b7

True

kglr
  • 394,356
  • 18
  • 477
  • 896