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$
  • $\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$
  • 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$
  • $\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$
  • $\begingroup$ Very amusing, thanks. $\endgroup$ – Fred Simons 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.