14
$\begingroup$

I have the following matrix

mat={{0,a,b},{c,0,d},{0,0,e}}

I would like to replace the zero elements of it with 1 and the remaining with zero. The first step would be

mat/.{0->1}

However I have not idea how to use the replace operator /. for indicating all the elements that do not match a pattern.

Is it possible to do it?

$\endgroup$
2
  • $\begingroup$ What type are the other elements ? Symbols ? Strings ? the pattern should be constructed to match those. $\endgroup$
    – Lotus
    Jul 5 '17 at 10:26
  • $\begingroup$ This will do if the other elements are Symbols. mat /. {0 -> 1, (x_Symbol /; x =!= List) -> 0} Can you guess why we need to exclude List in the pattern ? $\endgroup$
    – Lotus
    Jul 5 '17 at 10:32
7
$\begingroup$
SetAttributes[rep, Listable]
rep[_] := 0
rep[0] := 1

rep @ mat

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

Update

This method can easily be extended by adding new rules to rep, f.e.:

rep[a_ /; MemberQ[{-t, t, -s, s}, a]] := a

Now

rep @ {{0, a12, s}, {a21, a22, -s}, {t, s, -t}}

{{1, 0, s}, {0, 0, -s}, {t, s, -t}}

$\endgroup$
4
  • 1
    $\begingroup$ you can also do: rep[a : -t | t | -s | s] := a $\endgroup$
    – kglr
    Jul 5 '17 at 20:06
  • $\begingroup$ Thanks, always nice to have Alternatives :) $\endgroup$
    – eldo
    Jul 5 '17 at 20:18
  • $\begingroup$ Thank you so much ! $\endgroup$
    – Galuoises
    Jul 6 '17 at 15:24
  • $\begingroup$ You're welcome - and thanks for the accept $\endgroup$
    – eldo
    Jul 6 '17 at 15:28
16
$\begingroup$
Replace[mat, {0 -> 1, _ -> 0}, {2}]
(* or Replace[mat, {0 -> 1, Except[0] -> 0}, {2}] *)

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

Also

1 - Unitize @ ArrayComponents @ mat

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

And a variation of @Lotus's suggestion for ReplaceAll:

mat /. {0 -> 1, Except[List, _Symbol] -> 0}

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

Update: Can this method be generalised to a matrix made of mixed symbols: e.g. {{a11, a12, s}, {a21,a22, -s},{t,s,-t}} and I want to keep only the s and t symbols ...

Replace and ReplaceAll can be used to deal with this case:

mat2 = {{a11, a12, s}, {a21, a22, -s}, {t, s, -t}};

Replace[#, Except[s | t | Times[_, s | t]] :> 0, {2}] & @ mat2

{{0, 0, s}, {0, 0, -s}, {t, s, -t}}

mat2 /. Except[s | t | Times | List, _Symbol] :> 0

{{0, 0, s}, {0, 0, -s}, {t, s, -t}}

$\endgroup$
4
  • $\begingroup$ Can this method be generalised to a matrix made of mixed symbols: e.g. {{a11, a12, s}, {a21,a22, -s},{t,s,-t}} and I want to keep only the s and t symbols and remove all the a_{ij}? $\endgroup$
    – Galuoises
    Jul 5 '17 at 13:18
  • $\begingroup$ oh man you already did ArrayComponents? So much for my contribution. :^) $\endgroup$
    – Mr.Wizard
    Jul 5 '17 at 14:41
  • $\begingroup$ @Galuoises, updated with how the case in your comment can be handled with Replace and ReplaceAll. $\endgroup$
    – kglr
    Jul 5 '17 at 19:23
  • $\begingroup$ Thank you so much! $\endgroup$
    – Galuoises
    Jul 6 '17 at 15:24
7
$\begingroup$

Or:

mat={{0,a,b},{c,0,d},{0,0,e}};

Map[If[#===0,1,0]&, mat, {2}]

(* {{1,0,0},{0,1,0},{1,1,0}} *)

$\endgroup$
5
$\begingroup$
mat = {{0, a, b}, {c, 0, d}, {0, 0, e}};

1 - mat/(mat /. 0 -> 1)
{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}
$\endgroup$
1
  • $\begingroup$ Very amusing, thanks. $\endgroup$ Jul 5 '17 at 15:33
3
$\begingroup$

If the OP will accept a SparseArray:

SparseArray[Position[mat, 0] -> 1, Length@mat] // Normal

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

$\endgroup$
1
$\begingroup$
ReplacePart[mat, {Position[mat, Except[List, _Symbol]] -> 0, Position[mat, 0] -> 1}]
(* {{1, 0, 0}, {0, 1, 0}, {1, 1, 0}} *)
$\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.