# Replace elements that do not match a pattern

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?

• What type are the other elements ? Symbols ? Strings ? the pattern should be constructed to match those. Commented Jul 5, 2017 at 10:26
• 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 ? Commented Jul 5, 2017 at 10:32

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}}

• you can also do: rep[a : -t | t | -s | s] := a
– kglr
Commented Jul 5, 2017 at 20:06
• Thanks, always nice to have Alternatives :)
– eldo
Commented Jul 5, 2017 at 20:18
• Thank you so much ! Commented Jul 6, 2017 at 15:24
• You're welcome - and thanks for the accept
– eldo
Commented Jul 6, 2017 at 15:28
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}}

• 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}? Commented Jul 5, 2017 at 13:18
• oh man you already did ArrayComponents? So much for my contribution. :^) Commented Jul 5, 2017 at 14:41
• @Galuoises, updated with how the case in your comment can be handled with Replace and ReplaceAll.
– kglr
Commented Jul 5, 2017 at 19:23
• Thank you so much! Commented Jul 6, 2017 at 15:24

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}} *)

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

1 - mat/(mat /. 0 -> 1)

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

• Very amusing, thanks. Commented Jul 5, 2017 at 15:33

If the OP will accept a SparseArray:

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


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

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


Using MapCases by Richard Hennigan (Wolfram Research)

MapCases = ResourceFunction["MapCases"];

MapCases[0 &, mat /. 0 :> 1, _Symbol, {2}]


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

ReplacePart[mat, {Position[mat, Except[List, _Symbol]] -> 0, Position[mat, 0] -> 1}]
(* {{1, 0, 0}, {0, 1, 0}, {1, 1, 0}} *)

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


Using ReplaceList:

ReplaceList[mat, {___, a_List, ___} :> Map[Boole[SameQ[#, 0]] &]@a]


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

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


A hash-free variant of E. Chan-López answer using SameAs (new in 13.1)

ReplaceList[mat, {___, a_, ___} :> Boole @* SameAs[0] /@ a]


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