8000 BUG: removed unnecesary warning from financial.pmt method · githubmlai/numpy@f116c39 · GitHub
[go: up one dir, main page]

Skip to content

Commit f116c39

Browse files
committed
BUG: removed unnecesary warning from financial.pmt method
Previous implementation would cause divide by zero and hence warning since "fact" variable was calculated for all rates (both zero and non-zero) but then zero rates would be masked with a where equality. Changed implementation to apply non-zero rates using "np.divide( numerator, denominator, where=mask_of_zero_values)"and then apply zero rates with "np.copyto". Also updated documentation to show exact formulas that are being calculated. Done with help of Sebastian Berg in Austin,TX! Fixes issue numpy#5046
1 parent 49617ac commit f116c39

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

numpy/lib/financial.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def pmt(rate, nper, pv, fv=0, when='end'):
148148
Number of compounding periods
149149
pv : array_like
150150
Present value
151-
fv : array_like, optional
151+
fv : array_like (optional)
152152
Future value (default = 0)
153153
when : {{'begin', 1}, {'end', 0}}, {string, int}
154154
When payments are due ('begin' (1) or 'end' (0))
@@ -163,17 +163,24 @@ def pmt(rate, nper, pv, fv=0, when='end'):
163163
164164
Notes
165165
-----
166-
The payment is computed by solving the equation::
166+
When `rate != 0``: the payment is computed by solving the equation::
167167
168168
fv +
169169
pv*(1 + rate)**nper +
170170
pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
171171
172-
or, when ``rate == 0``::
172+
Solving for pmt yields::
173+
174+
pmt = -(fv + pv*(1 + rate)**nper) * rate / ( (1 + rate*when) * ((1 + rate)**nper -1) )
175+
176+
When ``rate == 0``:the payment is computed by instead solving the equation::
173177
174178
fv + pv + pmt * nper == 0
175179
176-
for ``pmt``.
180+
Solving for pmt yields::
181+
182+
pmt = -(fv + pv) / nper
183+
177184
178185
Note that computing a monthly mortgage payment is only
179186
one use for this function. For example, pmt returns the
@@ -208,12 +215,15 @@ def pmt(rate, nper, pv, fv=0, when='end'):
208215
"""
209216
when = _convert_when(when)
210217
(rate, nper, pv, fv, when) = map(np.asarray, [rate, nper, pv, fv, when])
211-
temp = (1 + rate)**nper
212-
mask = (rate == 0.0)
213-
np.copyto(rate, 1.0, where=mask)
214-
z = np.zeros(np.broadcast(rate, nper, pv, fv, when).shape)
215-
fact = np.where(mask != z, nper + z, (1 + rate*when)*(temp - 1)/rate + z)
216-
return -(fv + pv*temp) / fact
218+
219+
# use different payment if rate == 0
220+
zero_rate_mask = rate == 0
221+
compounded_rate = (1 + rate)**nper
222+
payment = np.asarray(np.divide(-(fv + pv*compounded_rate)*rate,
223+
(1 + rate*when)*(compounded_rate - 1),
224+
where=~zero_rate_mask))
225+
np.copyto(payment, -(fv + pv)/nper, where=zero_rate_mask)
226+
return payment
217227

218228
def nper(rate, pmt, pv, fv=0, when='end'):
219229
"""

0 commit comments

Comments
 (0)
0