[Numpy-svn] r4986 - in trunk/numpy: . lib lib/tests ma

numpy-svn@scip... numpy-svn@scip...
Mon Apr 7 23:56:16 CDT 2008


Author: oliphant
Date: 2008-04-07 23:56:12 -0500 (Mon, 07 Apr 2008)
New Revision: 4986

Modified:
   trunk/numpy/__init__.py
   trunk/numpy/lib/__init__.py
   trunk/numpy/lib/financial.py
   trunk/numpy/lib/tests/test_financial.py
   trunk/numpy/ma/API_CHANGES.txt
   trunk/numpy/ma/README.txt
Log:
Add docs and examples for financial functions.

Modified: trunk/numpy/__init__.py
===================================================================
--- trunk/numpy/__init__.py	2008-04-08 00:10:47 UTC (rev 4985)
+++ trunk/numpy/__init__.py	2008-04-08 04:56:12 UTC (rev 4986)
@@ -40,7 +40,7 @@
         return loader(*packages, **options)
 
     import add_newdocs
-    __all__ = ['add_newdocs',]
+    __all__ = ['add_newdocs']
 
     pkgload.__doc__ = PackageLoader.__call__.__doc__
     import testing

Modified: trunk/numpy/lib/__init__.py
===================================================================
--- trunk/numpy/lib/__init__.py	2008-04-08 00:10:47 UTC (rev 4985)
+++ trunk/numpy/lib/__init__.py	2008-04-08 04:56:12 UTC (rev 4986)
@@ -16,6 +16,7 @@
 from utils import *
 from arraysetops import *
 from io import *
+from financial import *
 import math
 
 __all__ = ['emath','math']
@@ -31,6 +32,7 @@
 __all__ += utils.__all__
 __all__ += arraysetops.__all__
 __all__ += io.__all__
+__all__ += financial.__all__
 
 def test(level=1, verbosity=1):
     from numpy.testing import NumpyTest

Modified: trunk/numpy/lib/financial.py
===================================================================
--- trunk/numpy/lib/financial.py	2008-04-08 00:10:47 UTC (rev 4985)
+++ trunk/numpy/lib/financial.py	2008-04-08 04:56:12 UTC (rev 4986)
@@ -1,10 +1,9 @@
 # Some simple financial calculations
 #  patterned after spreadsheet computations.
-from numpy import log, where
 import numpy as np
 
-__all__ = ['fv', 'pmt', 'nper', 'ipmt', 'ppmt', 'pv', 'rate', 'irr', 'npv', 
-           'mirr']
+__all__ = ['fv', 'pmt', 'nper', 'ipmt', 'ppmt', 'pv', 'rate', 
+           'irr', 'npv', 'mirr']
 
 _when_to_num = {'end':0, 'begin':1,
                 'e':0, 'b':1,
@@ -15,6 +14,14 @@
 
 eqstr = """
 
+                  nper       / (1 + rate*when) \   /        nper   \  
+  fv + pv*(1+rate)    + pmt*|-------------------|*| (1+rate)    - 1 | = 0
+                             \     rate        /   \               /
+
+       fv + pv + pmt * nper = 0  (when rate == 0)
+
+where (all can be scalars or sequences)
+
     Parameters
     ---------- 
     rate : 
@@ -26,51 +33,102 @@
     pv :
         Present value
     fv :
-        Future value
+        Future value 
     when : 
         When payments are due ('begin' (1) or 'end' (0))
                                                                    
-                   nper       / (1 + rate*when) \   /        nper   \  
-   fv + pv*(1+rate)    + pmt*|-------------------|*| (1+rate)    - 1 | = 0
-                              \     rate        /   \               /
-
-           fv + pv + pmt * nper = 0  (when rate == 0)
 """
 
+def _convert_when(when):    
+    try:
+        return _when_to_num[when]
+    except KeyError:
+        return [_when_to_num[x] for x in when]
+
+
 def fv(rate, nper, pmt, pv, when='end'):
     """future value computed by solving the equation
-
-    %s
-    """ % eqstr
-    when = _when_to_num[when]
+    """
+    when = _convert_when(when)
+    rate, nper, pmt, pv, when = map(np.asarray, [rate, nper, pmt, pv, when])
     temp = (1+rate)**nper
-    fact = where(rate==0.0, nper, (1+rate*when)*(temp-1)/rate)
+    miter = np.broadcast(rate, nper, pmt, pv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate==zer, nper+zer, (1+rate*when)*(temp-1)/rate+zer)
     return -(pv*temp + pmt*fact)
+fv.__doc__ += eqstr + """
+Example
+--------
 
+What is the future value after 10 years of saving $100 now, with
+  an additional monthly savings of $100.  Assume the interest rate is
+  5% (annually) compounded monthly?
+
+>>> fv(0.05/12, 10*12, -100, -100)
+15692.928894335748
+
+By convention, the negative sign represents cash flow out (i.e. money not
+  available today).  Thus, saving $100 a month at 5% annual interest leads
+  to $15,692.93 available to spend in 10 years.
+"""
+
 def pmt(rate, nper, pv, fv=0, when='end'):
     """Payment computed by solving the equation
-
-    %s
-    """ % eqstr
-    when = _when_to_num[when]
+    """
+    when = _convert_when(when)
+    rate, nper, pv, fv, when = map(np.asarray, [rate, nper, pv, fv, when])
     temp = (1+rate)**nper
-    fact = where(rate==0.0, nper, (1+rate*when)*(temp-1)/rate) 
+    miter = np.broadcast(rate, nper, pv, fv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate==zer, nper+zer, (1+rate*when)*(temp-1)/rate+zer) 
     return -(fv + pv*temp) / fact
+pmt.__doc__ += eqstr + """
+Example
+-------
 
+What would the monthly payment need to be to pay off a $200,000 loan in 15 
+  years at an annual interest rate of 7.5%?
+
+>>> pmt(0.075/12, 12*15, 200000)
+-1854.0247200054619
+
+In order to pay-off (i.e. have a future-value of 0) the $200,000 obtained 
+  today, a monthly payment of $1,854.02 would be required.
+"""
+
 def nper(rate, pmt, pv, fv=0, when='end'):
     """Number of periods found by solving the equation
-
-    %s
-    """ % eqstr
-    when = _when_to_num[when]
+    """
+    when = _convert_when(when)
+    rate, pmt, pv, fv, when = map(np.asarray, [rate, pmt, pv, fv, when])
     try:
         z = pmt*(1.0+rate*when)/rate
     except ZeroDivisionError:
         z = 0.0
     A = -(fv + pv)/(pmt+0.0)
-    B = (log(fv-z) - log(pv-z))/log(1.0+rate)
-    return where(rate==0.0, A, B) + 0.0
+    B = np.log((-fv+z) / (pv+z))/np.log(1.0+rate)
+    miter = np.broadcast(rate, pmt, pv, fv, when)
+    zer = np.zeros(miter.shape)
+    return np.where(rate==zer, A+zer, B+zer) + 0.0
+nper.__doc__ += eqstr + """
+Example
+-------
 
+If you only had $150 to spend as payment, how long would it take to pay-off
+  a loan of $8,000 at 7% annual interest?
+
+>>> nper(0.07/12, -150, 8000)
+64.073348770661852
+
+So, over 64 months would be required to pay off the loan.
+
+The same analysis could be done with several different interest rates and/or
+    payments and/or total amounts to produce an entire table.
+
+>>> nper(*(ogrid[0.06/12:0.071/12:0.005/12, -100:-201:50, 6000:8000:1000]))
+
+"""
+
 def ipmt(rate, per, nper, pv, fv=0.0, when='end'):
     raise NotImplementedError
 
@@ -80,13 +138,15 @@
 
 def pv(rate, nper, pmt, fv=0.0, when='end'):
     """Number of periods found by solving the equation
-
-    %s
-    """ % eqstr
-    when = _when_to_num[when]
+    """
+    when = _convert_when(when)
+    rate, nper, pmt, fv, when = map(np.asarray, [rate, nper, pmt, fv, when])
     temp = (1+rate)**nper
-    fact = where(rate == 0.0, nper, (1+rate*when)*(temp-1)/rate)
+    miter = np.broadcast(rate, nper, pmt, fv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate == zer, nper+zer, (1+rate*when)*(temp-1)/rate+zer)
     return -(fv + pmt*fact)/temp
+pv.__doc__ += eqstr
 
 # Computed with Sage
 #  (y + (r + 1)^n*x + p*((r + 1)^n - 1)*(r*w + 1)/r)/(n*(r + 1)^(n - 1)*x - p*((r + 1)^n - 1)*(r*w + 1)/r^2 + n*p*(r + 1)^(n - 1)*(r*w + 1)/r + p*((r + 1)^n - 1)*w/r)    
@@ -105,10 +165,9 @@
 #  g'(r) is the derivative with respect to r.
 def rate(nper, pmt, pv, fv, when='end', guess=0.10, tol=1e-6, maxiter=100):
     """Number of periods found by solving the equation
-
-    %s
-    """ % eqstr
-    when = _when_to_num[when]
+    """
+    when = _convert_when(when)
+    nper, pmt, pv, fv, when = map(np.asarray, [nper, pmt, pv, fv, when])
     rn = guess
     iter = 0
     close = False
@@ -123,6 +182,7 @@
         return np.nan + rn
     else:
         return rn
+rate.__doc__ += eqstr
     
 def irr(values):
     """Internal Rate of Return

Modified: trunk/numpy/lib/tests/test_financial.py
===================================================================
--- trunk/numpy/lib/tests/test_financial.py	2008-04-08 00:10:47 UTC (rev 4985)
+++ trunk/numpy/lib/tests/test_financial.py	2008-04-08 04:56:12 UTC (rev 4986)
@@ -1,5 +1,5 @@
 """
-from numpy.lib.financial import *
+from numpy import *
 
 >>> rate(10,0,-3500,10000)
 0.11069085371426901

Modified: trunk/numpy/ma/API_CHANGES.txt
===================================================================
--- trunk/numpy/ma/API_CHANGES.txt	2008-04-08 00:10:47 UTC (rev 4985)
+++ trunk/numpy/ma/API_CHANGES.txt	2008-04-08 04:56:12 UTC (rev 4986)
@@ -127,12 +127,4 @@
 
 The ``anom`` method returns the deviations from the average (anomalies).
 
-``varu`` and ``stdu``
----------------------
 
-These methods return unbiased estimates of the variance and standard deviation
-respectively. An unbiased estimate is obtained by dividing the sum of the
-squared anomalies by ``n-1`` instead of ``n`` for the biased estimates, where
-``n`` is the number of unmasked elements along the given axis.
-
-

Modified: trunk/numpy/ma/README.txt
===================================================================
--- trunk/numpy/ma/README.txt	2008-04-08 00:10:47 UTC (rev 4985)
+++ trunk/numpy/ma/README.txt	2008-04-08 04:56:12 UTC (rev 4986)
@@ -74,7 +74,6 @@
 
  * the *mr_* function mimics *r_* for masked arrays.
  * the *anom* method returns the anomalies (deviations from the average)
- * the *stdu* and *varu* return unbiased estimates of the standard deviation and variance, respectively.
 
 Using the new package with numpy.core.ma
 ----------------------------------------



More information about the Numpy-svn mailing list