Prev Next more_py

@(@\newcommand{\B}[1]{ {\bf #1} } \newcommand{\R}[1]{ {\rm #1} }@)@
Steps To Add More Python Functions

Purpose
This section outlines the steps for adding more python functionality to cppad_py. This is done by example showing how the py_fun_new_dynamic was added. This example case was chosen because it required both changing one python function, py_independent , and adding a new python function, py_fun_new_dynamic .

Documentation

independent
The python file lib/python/independent.py was edited to add the following syntax documentation:
     (
axadynamic) = cppad_py::independent(xdynamic)
and the extra return value was documented; see adynamic .

new_dynamic
The cpp_fun_new_dynamic documentation was added in the file lib/python/fun_new_dynamic.py. In addition, the OMhelp command
 
     %lib/python/fun_new_dynamic.py
was added to the file lib/python/fun.py.

Example
An example file was added to the documentation, below the py_independent section, using the OMhelp commands: $children% lib/example/python/fun_dynamic_xam.py %$$ In addition, a reference to this example was added under the example heading in the independent documentation.

Implementation

independent
The independent function in lib/python/independent.py was changed to handle dynamic parameters as follows:
import cppad_py
import numpy
def independent(x, dynamic = None) :
     """
     ax = independent(x)
     creates the indepedent numpy vector ax, with value equal numpy vector x,
     and starts recording a_double operations.
     """
     # convert x -> u
     dtype    = float
     #
     nx = x.size
     if dynamic is None :
          syntax   = 'independent(x)'
          u = cppad_py.utility.numpy2vec(x, dtype, nx, syntax, 'x')
          av = cppad_py.swig.independent(u)
          ax = cppad_py.utility.vec2numpy(av, av.size());
          return ax
     #
     nd       = dynamic.size
     syntax   = 'independent(x, dynamic)'
     u = cppad_py.utility.numpy2vec(x, dtype, nx, syntax, 'x')
     v = cppad_py.utility.numpy2vec(dynamic, dtype, nd, syntax, 'dynamic')
     a_both   = cppad_py.swig.independent(u, v)
     ax       = numpy.empty(nx,       dtype=cppad_py.a_double)
     adynamic = numpy.empty(nd, dtype=cppad_py.a_double)
     # use copy constructor so a separate copy is made for numpy arrays
     for i in range(nx) :
          ax[i] = cppad_py.a_double( a_both[i] )
     for i in range(nd) :
          adynamic[i] = cppad_py.a_double( a_both[nx + i] )
     #
     return (ax, adynamic)

new_dynamic
The following function declaration was added to the d_fun class in the lib/python/fun.py file:

    def new_dynamic(self, dynamic) :
        return cppad_py.d_fun_new_dynamic(self.f, dynamic)
A similar declaration was added to the a_fun class.

fun_new_dynamic.py
The implementation of d_fun_new_dynamic and a_fun_new_dynamic were added to the file fun_new_dynamic.py

__init__.py
The following code was added to the file lib/python/__init__.py:
 
from cppad_py.fun_new_dynamic import a_fun_new_dynamic
from cppad_py.fun_new_dynamic import d_fun_new_dynamic

Example
The file lib/example/python/fun_dynamic_xam.py was added with the following contents: fun_dynamic_xam.py . In addition, in the file lib/example/python/check_all.py.in, % 'fun_dynamic_xam', % was added to the list of python example files.

Testing
You must do a git add for all of the new files before running bin/check_all.sh After all the changes above were implemented, bin/check_all.sh was run and the changes were made until the warnings and errors were fixed. The command
 
     grep 'fun_dynamic_xam' check_all.log
was used to make sure that the new python example / test was run. Note that the python files in cppad_py are copies of the python files in lib/python. So when you fix errors during testing, you need to fix the lib/python file. Also note that if a particular step in bin/check_all.sh is failing, you can just re-run that step to see if a particular fix works. Once the tests were working, the changes where checked into using git.
Input File: lib/python/more_py.omh