8
$\begingroup$

I just learned about Mr. Wizard's very efficient code here.

list=RandomChoice[{True,False},10^6];
AbsoluteTiming[l2=Developer`ToPackedArray@With[{True=1,False=0},Evaluate@list];]
(*{0.066533,Null}*)

Compare that to Boole.

AbsoluteTiming[l3=Boole[list];]
l2===l3
(*{0.262770,Null}*)
(* True *)

It seems we can make a faster Boole. I tried to use the code above to do that, but it doesn't work.

boole[list_]:=Developer`ToPackedArray@With[{True=1,False=0},Evaluate@list];
list={True,True,False,True,False};
boole[list]
(*{True,True,False,True,False}*)

Why doesn't boole above work, and how can it be fixed?

$\endgroup$
1
  • $\begingroup$ I suggest making the question explicit in the title (you're using an existing implementation and it doesn't work, rather than asking for possible implementations) -- $\endgroup$ – user202729 Oct 28 '18 at 15:07
9
$\begingroup$

The problem is the automatic module variable renaming that happens with With. You can use TracePrint to see this:

TracePrint[boole[list], _With]

With[{True\$=1,False\$=0},{True,True,False,True,False}]

{True, True, False, True, False}

One idea to circumvent this renaming is to use a pure function:

Clear[boole]
boole = Function[Developer`ToPackedArray @ With[{True = 1, False = 0}, #]];

Then:

boole[list]

{1, 1, 0, 1, 0}

$\endgroup$
2
  • $\begingroup$ Thank you. Wizard and Carl are both WL experts. I am using version 10. Is the With[{True=1,False-0} ,...] trick faster than Boole in version 11.3 ? $\endgroup$ – Ted Ersek Oct 27 '18 at 20:48
  • $\begingroup$ With 11.3 on linux boole order 10 times faster. $\endgroup$ – b.gates.you.know.what Oct 28 '18 at 7:33
8
$\begingroup$

See Using With to scope over pure functions, then try:

boole[list_] := With @@ Hold[{True = 1, False = 0}, list] // Developer`ToPackedArray
$\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.