2
$\begingroup$

The following will convey the idea: build a new vector based on an existing condition (boolean) vector. For simplicity, I'll build the conditioning vector (cond) in a known fashion.

(* setup: 3 vectors, one of which is boolean *)
init = RandomInteger[10, 10]
subs = RandomInteger[{11, 20}, 10]
cond = Thread[init > 5]

Here is one approach to building the desired vector:

MapThread[If, {cond, init, subs}]

Is this a good approach, speedwise? Am I overlooking a builtin?

$\endgroup$
1
  • 3
    $\begingroup$ try also init + UnitStep[5 - init] (subs - init)? $\endgroup$
    – kglr
    May 18 at 23:08
2
$\begingroup$
Clear["Global`*"]

$Version

(* "12.2.0 for Mac OS X x86 (64-bit) (December 12, 2020)" *)

kglr's solution is fast. The performance differences are very dramatic for larger lists

Manipulate[
 SeedRandom[1234];
 init = RandomInteger[10, n];
 subs = RandomInteger[{11, 20}, n];
 cond = Thread[init > 5];
 t1 = RepeatedTiming[sol1 = (* Alan *)
      MapThread[If[#1, #2, #3] &, {cond, init, subs}];][[1]];
 t2 = RepeatedTiming[sol2 = (* Hanlon *)
      If @@@ Thread[{cond, init, subs}];][[1]];
 t3 = RepeatedTiming[sol3 =(* kglr *)
      init + UnitStep[5 - init] (subs - init);][[1]];
 Grid[
  Prepend[{{sol1 === sol2 === sol3, t1/t3, t2/t3}},
   {"Equal", "t1/t3", "t2/t3"}],
  Frame -> All],
 {{n, 10}, 10^Range[5]}]

enter image description here

$\endgroup$
1
  • $\begingroup$ With the larger vectors the speed difference is startling. $\endgroup$
    – Alan
    May 19 at 14:18

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.