Skip to content

Commit 370abb0

Browse files
committed
ENH: Altered IRR function to accept 2D-array
IRR function was changed to accept 2D-arrays as input. A for-loop was included to iterate over each row of the array, generate an IRR, and append its value to a results array.
1 parent 63aa1b1 commit 370abb0

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

numpy_financial/_financial.py

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -803,18 +803,20 @@ def irr(values, *, raise_exceptions=False, selection_logic=_irr_default_selectio
803803
0.0886
804804
805805
"""
806-
values = np.atleast_1d(values)
807-
if values.ndim != 1:
808-
raise ValueError("Cashflows must be a rank-1 array")
809-
810-
# If all values are of the same sign no solution exists
811-
# we don't perform any further calculations and exit early
812-
same_sign = np.all(values > 0) if values[0] > 0 else np.all(values < 0)
813-
if same_sign:
814-
if raise_exceptions:
815-
raise NoRealSolutionError('No real solution exists for IRR since all '
816-
'cashflows are of the same sign.')
817-
return np.nan
806+
values = np.atleast_2d(values)
807+
if values.ndim not in [1, 2]:
808+
raise ValueError("Cashflows must be a 2D array")
809+
810+
irr_results = []
811+
for row in values:
812+
# If all values are of the same sign, no solution exists
813+
# We don't perform any further calculations and exit early
814+
same_sign = np.all(row > 0) if row[0] > 0 else np.all(row < 0)
815+
if same_sign:
816+
if raise_exceptions:
817+
raise NoRealSolutionError('No real solution exists for IRR since all '
818+
'cashflows are of the same sign.')
819+
irr_results.append(np.nan)
818820

819821
# We aim to solve eirr such that NPV is exactly zero. This can be framed as
820822
# simply finding the closest root of a polynomial to a given initial guess
@@ -833,25 +835,25 @@ def irr(values, *, raise_exceptions=False, selection_logic=_irr_default_selectio
833835
#
834836
# which we solve using Newton-Raphson and then reverse out the solution
835837
# as eirr = g - 1 (if we are close enough to a solution)
836-
837-
g = np.roots(values)
838-
eirr = np.real(g[np.isreal(g)]) - 1
839-
840-
# realistic IRR
841-
eirr = eirr[eirr>=-1]
842-
843-
# if no real solution
844-
if len(eirr) == 0:
845-
if raise_exceptions:
846-
raise NoRealSolutionError("No real solution is found for IRR.")
847-
return np.nan
848-
849-
# if only one real solution
850-
if len(eirr) == 1:
851-
return eirr[0]
852-
853-
eirr = selection_logic(eirr)
854-
return eirr
838+
g = np.roots(row)
839+
eirr = np.real(g[np.isreal(g)]) - 1
840+
841+
# Realistic IRR
842+
eirr = eirr[eirr >= -1]
843+
844+
# If no real solution
845+
if len(eirr) == 0:
846+
if raise_exceptions:
847+
raise NoRealSolutionError("No real solution is found for IRR.")
848+
irr_results.append(np.nan)
849+
# If only one real solution
850+
if len(eirr) == 1:
851+
irr_results.append(eirr[0])
852+
853+
eirr = selection_logic(eirr)
854+
irr_results.append(eirr)
855+
856+
return np.array(irr_results)
855857

856858

857859
def npv(rate, values):

0 commit comments

Comments
 (0)