def preduce_yield(vl, vec, pred):
step = 1
ix = list(range(vl))
while step < vl:
step *= 2
for i in range(0, vl, step):
other = i + step // 2
ci = ix[i]
oi = ix[other] if other < vl else None
other_pred = other < vl and pred[oi]
if pred[ci] and other_pred:
yield ci, oi
elif other_pred:
ix[i] = oi
def preduce_y(vl, vec, pred):
for i, other in preduce_yield(vl, vec, pred):
vec[i] += vec[other]