FunctionWrap.cxx

Go to the documentation of this file.
00001 
00012 // include first to avoid _POSIX_C_SOURCE warning.
00013 #include <boost/python.hpp>
00014 
00015 #ifdef HAVE_CONFIG_H
00016 // for boost defect
00017 #include "config.h"
00018 #endif
00019 
00020 
00021 #include "FunctionWrap.h"
00022 #ifndef BOOST_DEFECT
00023 
00024 #include <stdexcept>
00025 
00026 using std::string;
00027 using std::vector;
00028 
00029 using namespace boost::python;
00030 
00031 namespace hippodraw {
00032   namespace Python {
00033     void
00034     export_FunctionBase ()
00035     {
00036       class_ < FunctionWrap, std::auto_ptr < FunctionWrap> >
00037         ( "FunctionBase",
00038           "The base class for raw functions.   FunctionBase objects need to\n"
00039           "wrapped with Function objects to be displayed.   FunctionBase\n"
00040           "can be derived from and cloned so they can be added to the\n"
00041           "FunctionFactory.",
00042           init < const FunctionBase & >
00043           ( "FunctionBase () -> FunctionBase\n"
00044             "FunctionBase ( FunctionBase ) -> FunctionBase\n"
00045             "\n"
00046             "Constructors of the FunctionBase object.\n" ) )
00047 
00048         .def ( init <> () )
00049 
00050         .def ( init < const FunctionWrap & > () )
00051 
00052         .def ( "initialize", &FunctionWrap::initialize,
00053                "initialize () -> None\n"
00054                "\n"
00055                "Initializes the function parameter values and the names.\n"
00056                "The number of parameters is taken from the number of names." )
00057 
00058         .def ( "name", &FunctionBase::name,
00059                return_value_policy < copy_const_reference > (),
00060                "name () -> string\n"
00061                "\n"
00062                "Returns the name of the function." )
00063 
00064         .def ( "setName", &FunctionWrap::setName,
00065                "setName ( string ) -> None\n"
00066                "\n"
00067                "Sets the name of the function." )
00068 
00069         .def ( "parmNames",
00070                &FunctionBase::parmNames,
00071                return_value_policy < copy_const_reference > (),
00072                "parmNames () -> sequence\n"
00073                "\n"
00074                "Returns the names of the parameters" )
00075 
00076         .def ( "setParmNames",
00077                &FunctionWrap::setParmNames,
00078                "setParmNames ( sequence ) -> None\n"
00079                "\n"
00080                "Sets the parameter names and re-sizes the parameters" )
00081 
00082         .def ( "setParameters", 
00083                ( void ( FunctionBase::* ) // function pointer cast
00084                ( const std::vector < double > & ) )  // function signature
00085                &FunctionBase::setParameters,
00086                "setParameters ( sequence ) -> None\n"
00087                "\n"
00088                "Sets the values of the parameters." )
00089 
00090         .def ( "getParameters", &FunctionBase::getParameters,
00091                return_value_policy < copy_const_reference > (),
00092                "getParameters () -> sequence\n"
00093                "\n"
00094                "Returns the current function parameter values." )
00095 
00096         ;
00097     }
00098   } // namespace Python
00099 } // namespace hippodraw
00100 
00101 using namespace hippodraw;
00102 
00103 FunctionWrap::
00104 FunctionWrap ( )
00105   : FunctionBase ()
00106 {
00107 }
00108 
00109 FunctionWrap::
00110 FunctionWrap ( const FunctionBase & base )
00111   : FunctionBase ( base )//,
00112 {
00113 }
00114 
00115 FunctionWrap::
00116 FunctionWrap ( const FunctionWrap & wrap )
00117   : FunctionBase ( wrap )
00118 {
00119 }
00120 
00121 FunctionWrap::
00122 ~FunctionWrap ()
00123 {
00124 #ifndef HAVE_OLD_PYTHON
00125   PyGILState_STATE state = PyGILState_Ensure ();
00126 
00127   extract<std::auto_ptr<FunctionWrap>&> x(get_owner(this));
00128   if ( x.check() ) x().release();
00129 
00130   PyGILState_Release ( state );
00131 #endif
00132 }
00133 
00134 template <class T>
00135 object
00136 FunctionWrap::
00137 get_owner(T* ) const // me
00138 {
00139       // Use secret interface to get the Python object
00140       // that owns *this.  I guess I will have to make that
00141       // interface public. -- Dave Abrahams
00142       return
00143 object ( handle<> ( borrowed ( detail::wrapper_base_::get_owner(*this))));
00144 }
00145 
00146 unsigned int
00147 FunctionWrap::
00148 dimensions () const
00149 {
00150   unsigned int dims = 0;
00151 #ifndef HAVE_OLD_PYTHON
00152   PyGILState_STATE state = PyGILState_Ensure ();
00153 
00154   if ( override member = this -> get_override ( "dimensions" ) ) {
00155     FunctionWrap * fw = const_cast < FunctionWrap * > ( this );
00156     object self = get_owner ( fw );
00157     dims = call_method < unsigned int > ( self.ptr(), "dimensions" );
00158   }
00159   else { // didn't override it
00160     dims = FunctionBase::dimensions ();
00161   }
00162   PyGILState_Release ( state );
00163 #endif
00164 
00165   return dims;
00166 }
00167 
00168 bool
00169 FunctionWrap::
00170 hasDerivatives () const
00171 {
00172   bool yes = false;
00173 
00174   if ( override member = this -> get_override ( "derivByParm" ) ) {
00175     yes = true;
00176   }
00177 
00178   return yes;
00179 }
00180 
00181 FunctionBase *
00182 FunctionWrap::
00183 clone () const
00184 {
00185 #ifndef HAVE_OLD_PYTHON
00186   PyGILState_STATE state = PyGILState_Ensure ();
00187 
00188   object py_result;
00189 
00190   if (override clone = this->get_override("clone")) {
00191      try {
00192         // The Python class author overrode clone; do
00193         // whatever she says
00194         py_result ( clone() );
00195      } catch ( error_already_set & ) {
00196         PyErr_Print ();
00197         handle_exception ();
00198         PyGILState_Release ( state );
00199         return 0;
00200      }
00201   } else {
00202      FunctionWrap * t = const_cast < FunctionWrap * > ( this );
00203      try {
00204         object self = get_owner ( t );
00205         // Find its most-derived Python class
00206         object my_class = self.attr("__class__");
00207         // call the default constructor
00208         py_result = my_class ( );
00209      } catch ( error_already_set & ) {
00210         PyErr_Print ();
00211         handle_exception ();
00212         PyGILState_Release ( state );
00213         return 0;
00214      }
00215   }
00216 
00217   FunctionWrap* result = extract<FunctionWrap*>(py_result);
00218 
00219   // Make the C++ result control the destiny of the Python result.
00220   result->invert_ownership = py_result;
00221   PyGILState_Release ( state );
00222 
00223   return result;
00224 
00225 #else // old Python
00226   return 0;
00227 #endif
00228 }
00229 
00234 void
00235 FunctionWrap::
00236 setName ( const std::string & name )
00237 {
00238   FunctionBase::setName ( name.c_str() );
00239 }
00240 
00241 void
00242 FunctionWrap::
00243 setParmNames ( const std::vector < std::string > & names )
00244 {
00245   m_parm_names = names;
00246   resize ();
00247 }
00248 
00253 double
00254 FunctionWrap::
00255 derivByParm ( int i , double x ) const
00256 {
00257 #ifndef HAVE_OLD_PYTHON
00258   double value = 0.;
00259   PyGILState_STATE state = PyGILState_Ensure ();
00260 
00261   FunctionWrap * t = const_cast < FunctionWrap * > ( this );
00262   object self = get_owner ( t );
00263 
00264   try {
00265     value = call_method < double, int, double > 
00266       ( self.ptr(), "derivByParm", i, x );
00267   }  catch ( ... ) {
00268     value = 0.;
00269   }
00270 
00271   PyGILState_Release ( state );
00272 
00273   return value;
00274 #else // old Python
00275   return 0;
00276 #endif
00277 }
00278 
00281 void
00282 FunctionWrap::
00283 initialize ()
00284 {
00285 #ifndef HAVE_OLD_PYTHON
00286   PyGILState_STATE state = PyGILState_Ensure ();
00287 
00288   FunctionWrap * t = const_cast < FunctionWrap * > ( this );
00289   object self = get_owner ( t );
00290   call_method < void > ( self.ptr(), "initialize" );
00291   resize ();
00292 
00293   PyGILState_Release ( state );
00294 #endif
00295 }
00296 
00301 double
00302 FunctionWrap::
00303 operator () ( double x ) const
00304 {
00305   double value = 0;
00306 
00307 #ifndef HAVE_OLD_PYTHON
00308   PyGILState_STATE state = PyGILState_Ensure ();
00309   FunctionWrap * t = const_cast < FunctionWrap * > ( this );
00310   object self = get_owner ( t );
00311 
00312   try {
00313     value = call_method < double, double > ( self.ptr(), "valueAt", x );
00314     PyGILState_Release ( state );
00315   }
00316   catch ( const error_already_set & ) {
00317     PyGILState_Release ( state );
00318 //     handle_exception ();
00319   }    
00320 #endif
00321 
00322   return value;
00323 }
00324 
00327 double
00328 FunctionWrap::
00329 operator () ( const std::vector < double > & x ) const
00330 {
00331   double value = 0;
00332 
00333 #ifndef HAVE_OLD_PYTHON
00334   PyGILState_STATE state = PyGILState_Ensure ();
00335   FunctionWrap * t = const_cast < FunctionWrap * > ( this );
00336   object self = get_owner ( t );
00337   unsigned int size = x.size();
00338 
00339   switch ( size ) {
00340   case 2 :
00341     value = call_method < double, double, double > 
00342       ( self.ptr(), "valueAt", x[0], x[1] );
00343     break;
00344   case 3 :
00345     value = call_method < double, double, double, double > 
00346       ( self.ptr(), "valueAt", x[0], x[1], x[2] );
00347     break;
00348   default:
00349     break;
00350   }
00351   PyGILState_Release ( state );
00352 #endif
00353 
00354   return value;
00355 }
00356 
00357 void
00358 FunctionWrap::
00359 initialParameters ( const FunctionHelper * )
00360 {
00361 }
00362 
00363 #endif // BOOST_DEFECT

Generated for HippoDraw Class Library by doxygen