15
$\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, 2017 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, 2017 at 10:32

6 Answers 6

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, 2017 at 20:06
  • $\begingroup$ Thanks, always nice to have Alternatives :) $\endgroup$
    – eldo
    Jul 5, 2017 at 20:18
  • $\begingroup$ Thank you so much ! $\endgroup$
    – Galuoises
    Jul 6, 2017 at 15:24
  • $\begingroup$ You're welcome - and thanks for the accept $\endgroup$
    – eldo
    Jul 6, 2017 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, 2017 at 13:18
  • $\begingroup$ oh man you already did ArrayComponents? So much for my contribution. :^) $\endgroup$
    – Mr.Wizard
    Jul 5, 2017 at 14:41
  • $\begingroup$ @Galuoises, updated with how the case in your comment can be handled with Replace and ReplaceAll. $\endgroup$
    – kglr
    Jul 5, 2017 at 19:23
  • $\begingroup$ Thank you so much! $\endgroup$
    – Galuoises
    Jul 6, 2017 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, 2017 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.