On Tue, Aug 25, 2009 at 11:38 PM, Charles R Harris<charlesr.har...@gmail.com> wrote: > So is it a bug in the test or a bug in the implementation? The problem is > that the slice values[1:] when > values = [-120000,39000,30000,21000,37000,46000] contains no negative > number and a nan is returned. This looks like a bug in the test. The > documentation also probably needs fixing. > > Chuck
There is a bug in the code, the nan is incorrectly raised. After correcting the nan (checking on the original, instead of shortened values), I got one failing test, that I corrected with the matching number from Openoffice. (The main problem that the function is more complicated than necessary, is because np.npv doesn't allow the inclusion of the investment in the initial period) This needs reviewing, since it's late here. Josef import numpy as np from numpy.testing import assert_almost_equal, assert_ from numpy import npv def mirr(values, finance_rate, reinvest_rate): """ Modified internal rate of return. Parameters ---------- values : array_like Cash flows (must contain at least one positive and one negative value) or nan is returned. finance_rate : scalar Interest rate paid on the cash flows reinvest_rate : scalar Interest rate received on the cash flows upon reinvestment Returns ------- out : float Modified internal rate of return """ values = np.asarray(values, dtype=np.double) initial = values[0] values1 = values[1:] n = values1.size pos = values1 > 0 neg = values1 < 0 if not (np.sum(values[values>0]) > 0 and np.sum(values[values<0]) < 0): return np.nan numer = np.abs(npv(reinvest_rate, values1*pos)) denom = np.abs(npv(finance_rate, values1*neg)) if initial > 0: return ((initial + numer) / denom)**(1.0/n)*(1 + reinvest_rate) - 1 else: return ((numer / (-initial + denom)))**(1.0/n)*(1 + reinvest_rate) - 1 #tests from testsuite and Skipper plus isnan test v1 = [-4500,-800,800,800,600,600,800,800,700,3000] print mirr(v1,0.08,0.055) assert_almost_equal(mirr(v1,0.08,0.055), 0.0666, 4) #incorrect test ? corrected v2 = [-120000,39000,30000,21000,37000,46000] print mirr(v2,0.10,0.12) assert_almost_equal(mirr(v2,0.10,0.12), 0.126094, 6) # corrected from OO v2 = [39000,30000,21000,37000,46000] assert_(np.isnan(mirr(v2,0.10,0.12))) v3 = [100,200,-50,300,-200] print mirr(v3,0.05,0.06) assert_almost_equal(mirr(v3,0.05,0.06), 0.3428, 4) #-------------- print mirr([100, 200, -50, 300, -200], .05, .06) assert_almost_equal(mirr((100, 200,-50, 300,-200), .05, .06), 0.342823387842, 4) V2 = [-4500,-800,800,800,600,600,800,800,700,3000] print mirr(V2, 0.08, 0.055) assert_almost_equal(mirr(V2, 0.08, 0.055), 0.06659718, 4) _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion