You can do the short-circuiting by hand, though I should add that this is probably only worth it in rather extreme cases.
Here is an example of 99 chained logical ands. The short circuiting is done either using the where keyword or using fancy indexing. The second but not the first gives a decent speed up for this example.
import numpy as np
a = np.random.random((1000,))*1.5
c = np.random.random((100, 1))*1.5
def direct():
return ((a+c) < np.arccos(np.cos(a+c)*0.99)).all(0)
def trickya():
out = np.ones(a.shape, '?')
for ci in c:
np.logical_and(out, np.less(np.add(a, ci, where=out), np.arccos(np.multiply(np.cos(np.add(a, ci, where=out), where=out), 0.99, where=out), where=out), where=out), out=out, where=out)
return out
def trickyb():
idx, = np.where((a+c[0]) < np.arccos(np.cos(a+c[0])*0.99))
for ci in c[1:]:
idx = idx[(a[idx]+ci) < np.arccos(np.cos(a[idx]+ci)*0.99)]
out = np.zeros(a.shape, '?')
out[idx] = True
return out
assert (direct()==trickya()).all()
assert (direct()==trickyb()).all()
from timeit import timeit
print('direct ', timeit(direct, number=100))
print('where kw', timeit(trickya, number=100))
print('indexing', timeit(trickyb, number=100))
Sample run:
direct 0.49512664100620896
where kw 0.494946873979643
indexing 0.17760096595156938
andandorshort circuit, but only for scalar conditions. With wholenumpywhole-array operations, each condition is evaluated, and then the values are combined. You'd have to usenumbaorcythonto construct a faster iterative test that implements short-circuiting.