Evaluate a selected number of cells in a matrix

Flatten @ MapIndexed[Drop, M]

{4, 1, 3, 0, 4, 0}


Here is one way:

Flatten @ ReplacePart[M, {n_, n_} -> Nothing]

Or, probably faster for bigger M:

Flatten @ Pick[M, IdentityMatrix@Length@M, 0]

Here's an approach that uses ArrayRules to associate each element with its indices, and then pick out the one you want using Cases. I use a Unique symbol as a default for ArrayRules so you get an explicit rule for every element; otherwise Cases won't grab all the elements you want:

Cases[ArrayRules[M, Unique[]], 
 HoldPattern[{i_, j_} -> a_] /; i != j :> a]
(* {4, 1, 3, 0, 4, 0} *)

Here's a fairly efficient way of doing it with procedural code, using Sow/Reap.

Reap[
  With[{n = Length@M},
   Do[If[i != j, Sow@M[[i, j]]], {i, 1, n}, {j, 1, n}]]] /.
{{Null, {result_}} :> result,
 {Null, {}} :> {}}

Here's a compiled procedural version that should be fast that's almost like yours, but avoids AppendTo, which is generally bad news (and I don't think will even compile).

compiled =
     Compile[{{matrix, _Real, 2}},
  Module[{
     m, n,
     result,
     fill = 0,
    },
    {m, n} = Dimensions[matrix];
    result = ConstantArray[0., m*n];

    Do[If[i != j, result[[++fill]] = matrix[[i, j]]], {i, 1, m}, {j, 1, n}];
    Take[result, fill]]];
 compiled[M]
 (* {4., 1., 3., 0., 4., 0.} *)

Because the function is compiled and I assumed the type of the matrix was real, everything got returned as a machine real.

Tags:

Matrix