|
13 | 13 |
|
14 | 14 | from decimal import Decimal
|
15 | 15 |
|
| 16 | +import numba as nb |
16 | 17 | import numpy as np
|
17 | 18 |
|
18 | 19 | __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):
|
851 | 852 | return np.nan
|
852 | 853 |
|
853 | 854 |
|
| 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 | + |
854 | 875 | def npv(rate, values):
|
855 | 876 | r"""Return the NPV (Net Present Value) of a cash flow series.
|
856 | 877 |
|
@@ -940,12 +961,10 @@ def npv(rate, values):
|
940 | 961 | shape = tuple(array.shape[0] for array in (rates, values))
|
941 | 962 | out = np.empty(shape=shape, dtype=dtype)
|
942 | 963 |
|
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) |
949 | 968 |
|
950 | 969 | return _return_ufunc_like(out)
|
951 | 970 |
|
|
0 commit comments