00001
00012
00013 #include <boost/python.hpp>
00014
00015 #ifdef HAVE_CONFIG_H
00016
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::* )
00084 ( const std::vector < double > & ) )
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 }
00099 }
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
00138 {
00139
00140
00141
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 {
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
00193
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
00206 object my_class = self.attr("__class__");
00207
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
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
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