8 Swap BitAnd arguments in the other BitAnd edited Jul 12 '17 at 6:40 JEM_Mosig 2,15488 silver badges2323 bronze badges One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[maskBitAnd[b, b]]mask]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  7 Swap arguments of BitAnd for consistency (does not change results) edited Jul 12 '17 at 3:26 JEM_Mosig 2,15488 silver badges2323 bronze badges One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[maskBitAnd[b, b]]mask]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  6 Make clear which solution is fastest edited Jul 11 '17 at 23:23 JEM_Mosig 2,15488 silver badges2323 bronze badges One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  The timing is comparable toor, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution (b - a)*mask + a.: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  The timing is comparable to @Shadowray's solution (b - a)*mask + a. One way to do this when a and b may contain any kind of symbolic expression could be With[{pos = Position[mask, 1]}, ReplacePart[a, Thread[pos -> Extract[b, pos]]] ]  Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position. Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution: a - BitAnd[a, mask] + BitAnd[b, mask]  or, even faster: BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]]  Here are the timings in comparison: a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First (* 0.012 *) BitOr[BitAnd[a, BitNot[mask]], BitAnd[mask, b]] // RepeatedTiming // First (* 0.0075 *)  the latter being even faster than @Shadowray's solution: (b - a)*mask + a // RepeatedTiming // First (* 0.0098 *)  5 Add Shadowray's code so that everything is in one palce. edited Jul 11 '17 at 22:50 JEM_Mosig 2,15488 silver badges2323 bronze badges 4 Replace c by mask edited Jul 11 '17 at 21:52 JEM_Mosig 2,15488 silver badges2323 bronze badges 3 added 103 characters in body edited Jul 11 '17 at 21:47 JEM_Mosig 2,15488 silver badges2323 bronze badges 2 added 78 characters in body edited Jul 11 '17 at 21:36 JEM_Mosig 2,15488 silver badges2323 bronze badges 1 answered Jul 11 '17 at 21:21 JEM_Mosig 2,15488 silver badges2323 bronze badges