[Numpy-discussion] mirr test correctly fails for given input.
Skipper Seabold
jsseabold@gmail....
Wed Aug 26 09:08:47 CDT 2009
On Wed, Aug 26, 2009 at 1:45 AM, <josef.pktd@gmail.com> wrote:
> On Tue, Aug 25, 2009 at 11:38 PM, Charles R
> Harris<charlesr.harris@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
>
Yes, the value in the tests that this v2 tests against is wrong. It
was the value returned by the old mirr but not excel or oocalc. This
is the correct one. I noted it in my patch, but it was hard to catch
since I didn't supply a diff. Now, I know...
>
> 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)
Skipper
More information about the NumPy-Discussion
mailing list