Skip to content

Commit 2d08783

Browse files
committed
ENH: NPV: Make hot path for native types
This commit introduces a native hot path using numba. This leads to an ~50x speed up on the `time_broadcast` benchmark with 100x100x100 dimension
1 parent 553647c commit 2d08783

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

numpy_financial/_financial.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from decimal import Decimal
1515

16+
import numba as nb
1617
import numpy as np
1718

1819
__all__ = ['fv', 'pmt', 'nper', 'ipmt', 'ppmt', 'pv', 'rate',
@@ -851,6 +852,26 @@ def irr(values, *, guess=None, tol=1e-12, maxiter=100, raise_exceptions=False):
851852
return np.nan
852853

853854

855+
@nb.njit
856+
def _npv_native(rates, values, out, zero, one):
857+
for i in range(rates.shape[0]):
858+
for j in range(values.shape[0]):
859+
acc = zero
860+
for t in range(values.shape[1]):
861+
acc += values[j, t] / ((one + rates[i]) ** t)
862+
out[i, j] = acc
863+
864+
865+
@nb.jit(forceobj=True)
866+
def _npv_decimal(rates, values, out, zero, one):
867+
for i in range(rates.shape[0]):
868+
for j in range(values.shape[0]):
869+
acc = zero
870+
for t in range(values.shape[1]):
871+
acc += values[j, t] / ((one + rates[i]) ** t)
872+
out[i, j] = acc
873+
874+
854875
def npv(rate, values):
855876
r"""Return the NPV (Net Present Value) of a cash flow series.
856877
@@ -940,12 +961,10 @@ def npv(rate, values):
940961
shape = tuple(array.shape[0] for array in (rates, values))
941962
out = np.empty(shape=shape, dtype=dtype)
942963

943-
for i in range(rates.shape[0]):
944-
for j in range(values.shape[0]):
945-
acc = zero
946-
for t in range(values.shape[1]):
947-
acc += values[j, t] / ((one + rates[i]) ** t)
948-
out[i, j] = acc
964+
if dtype == Decimal:
965+
_npv_decimal(rates, values, out, zero, one)
966+
else:
967+
_npv_native(rates, values, out, zero, one)
949968

950969
return _return_ufunc_like(out)
951970

0 commit comments

Comments
 (0)