// ======================================================================== // adaptive integration with singularities // ======================================================================== double NumericalDefiniteIntegral::QAGS ( _Function* F ) const { if( 0 == F ) { Exception("QAG::invalid function") ; } if ( m_a == m_b ) { m_result = 0 ; m_error = 0 ; // EXACT ! return m_result ; } // allocate workspace if( 0 == ws () ) { allocate () ; } // integration limits const double low = std::min ( m_a , m_b ) ; const double high = std::max ( m_a , m_b ) ; int ierror = gsl_integration_qags ( F->fn , low , high , m_epsabs , m_epsrel , size () , ws()->ws , &m_result , &m_error ); if( ierror ) { gsl_error( "NumericalDefiniteIntegral::QAGS " , __FILE__ , __LINE__ , ierror ) ; } // sign if ( m_a > m_b ) { m_result *= -1 ; } return m_result ; }
// ======================================================================== // adaptive integration with known singular points // ======================================================================== double NumericalDefiniteIntegral::QAGP( _Function* F ) const { if( 0 == F ) { Exception("QAGP::invalid function") ; } // no known singular points ? if( points().empty() || 0 == m_pdata ) { return QAGS( F ) ; } const size_t npts = points().size(); // use GSL int ierror = gsl_integration_qagp ( F->fn , m_pdata , npts , m_epsabs , m_epsrel , size () , ws()->ws , &m_result , &m_error ) ; if( ierror ) { gsl_error( "NumericalDefiniteIntegral::QAGI " , __FILE__ , __LINE__ , ierror ) ; } // the sign if ( m_a > m_b ) { m_result *= -1 ; } return m_result ; }
void GslInternal::integrate(double t_out){ double h = 1e-6; // starting step size for ode solver std::cout << "I wanna integrate from " << t_ << " to " << t_out << std::endl; int flag = gsl_odeiv_evolve_apply (evolve_ptr, control_ptr, step_ptr, &my_system, &t_, t_out, &h, &output(INTEGRATOR_XF).data()[0]); if(flag!=GSL_SUCCESS) gsl_error("Integrate",flag); std::cout << "GSL returned succes: " << flag << std::endl; }
void GslInternal::reset(int fsens_order, int asens_order){ if(monitored("reset")){ cout << "initial state: " << endl; cout << "p = " << input(INTEGRATOR_P) << endl; cout << "x0 = " << input(INTEGRATOR_X0) << endl; } // Reset timers t_res = t_fres = t_jac = t_lsolve = t_lsetup_jac = t_lsetup_fac = 0; // Get the time horizon t_ = t0_; int flag = gsl_odeiv_evolve_reset(evolve_ptr); if(flag!=GSL_SUCCESS) gsl_error("Reset",flag); output(INTEGRATOR_XF).set(input(INTEGRATOR_X0)); }
// ======================================================================== // adaptive integration on infinite interval // ======================================================================== double NumericalDefiniteIntegral::QAGI ( _Function* F ) const { // check the argument if ( 0 == F ) { Exception("::QAGI: invalid function"); } // allocate workspace if ( 0 == ws() ) { allocate() ; } int ierror = 0 ; if ( m_ia && m_ib ) { ierror = gsl_integration_qagi ( F->fn , m_epsabs , m_epsrel , size () , ws()->ws , &m_result , &m_error ) ; } else if ( m_ia ) { ierror = gsl_integration_qagil ( F->fn , m_b , m_epsabs , m_epsrel , size () , ws()->ws , &m_result , &m_error ) ; } else if ( m_ib ) { ierror = gsl_integration_qagiu ( F->fn , m_a , m_epsabs , m_epsrel , size () , ws()->ws , &m_result , &m_error ) ; } else { Exception ( "::QAGI: invalid mode" ) ; }; if( ierror ) { gsl_error( "NumericalDefiniteIntegral::QAGI" , __FILE__ , __LINE__ , ierror ) ;} return m_result ; }
// ======================================================================== // non-adaptive integration // ======================================================================== double NumericalDefiniteIntegral::QNG ( _Function* F ) const { if( 0 == F ) { Exception("QNG::invalid function") ; } // integration limits const double low = std::min ( m_a , m_b ) ; const double high = std::max ( m_a , m_b ) ; size_t neval = 0 ; int ierror = gsl_integration_qng ( F->fn , low , high , m_epsabs , m_epsrel , &m_result , &m_error , &neval ) ; if( ierror ) { gsl_error( "NumericalIndefiniteIntegral::QNG " , __FILE__ , __LINE__ , ierror ) ; } // sign if ( m_a > m_b ) { m_result *= -1 ; } return m_result ; }
static PyObject * PyGSL_odeiv_control_init(PyObject *self, PyObject *args, void * type) { int nargs = -1, tmp=0; double eps_abs, eps_rel, a_y, a_dydt; PyGSL_odeiv_step *step=NULL; PyGSL_odeiv_control *a_con=NULL; gsl_odeiv_control *(*evaluator_5)(double , double , double , double ) = NULL; gsl_odeiv_control *(*evaluator_3)(double , double ) = NULL; FUNC_MESS_BEGIN(); /* The arguments depend on the type of control */ if(type == (void *) gsl_odeiv_control_standard_new){ /* step, eps_abs, eps_rel, a_y, a_dydt */ nargs = 5; }else if(type == (void *) gsl_odeiv_control_y_new || type == (void *) gsl_odeiv_control_yp_new){ nargs = 3; }else{ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 2); gsl_error("Unknown control type", this_file, __LINE__ -2, GSL_EFAULT); goto fail; } assert(nargs > -1); switch(nargs){ case 5: tmp == PyArg_ParseTuple(args, "O!dddd:odeiv_control.__init__", &PyGSL_odeiv_step_pytype, &step, &eps_abs, &eps_rel, &a_y, &a_dydt); break; case 3: tmp == PyArg_ParseTuple(args, "O!dd:odeiv_control.__init__", &PyGSL_odeiv_step_pytype, &step, &eps_abs, &eps_rel); break; default: fprintf(stderr, "nargs = %d\n", nargs); gsl_error("Unknown number of arguments", this_file, __LINE__ -2, GSL_EFAULT); goto fail; break; } if(!step){ PyErr_SetString(PyExc_TypeError, "The first argument must be a step object!"); goto fail; } if(tmp){ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 2); return NULL; } a_con = PyObject_NEW(PyGSL_odeiv_control, &PyGSL_odeiv_control_pytype); if (NULL == a_con){ PyErr_NoMemory(); goto fail; } a_con->control=NULL; switch(nargs){ case 5: evaluator_5 = type; a_con->control = evaluator_5(eps_abs, eps_rel, a_y, a_dydt); break; case 3: evaluator_3 = type; a_con->control = evaluator_3(eps_abs, eps_rel); break; default: goto fail; } if (NULL == a_con->control){ PyErr_NoMemory(); goto fail; } assert(step); a_con->step = step; Py_INCREF(step); FUNC_MESS_END(); return (PyObject *) a_con; fail: FUNC_MESS("FAIL"); Py_XDECREF(a_con); return NULL; }
static PyObject * PyGSL_odeiv_step_init(PyObject *self, PyObject *args, PyObject *kwdict, const gsl_odeiv_step_type * odeiv_type) { PyObject *func=NULL, *jac=NULL, *o_params=NULL; PyGSL_odeiv_step *odeiv_step = NULL; static char * kwlist[] = {"dimension", "func", "jac", "args", NULL}; int dim, has_jacobian = 0; FUNC_MESS_BEGIN(); assert(args); if (0 == PyArg_ParseTupleAndKeywords(args, kwdict, "iOOO:odeiv_step.__init__", kwlist, &dim, &func, &jac, &o_params)){ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 2); return NULL; } if (dim <= 0){ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 1); gsl_error("The dimension of the problem must be at least 1", this_file, __LINE__ -2, GSL_EDOM); return NULL; } if(!PyCallable_Check(func)){ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 1); gsl_error("The function object is not callable!", this_file, __LINE__ -2, GSL_EBADFUNC); goto fail; } if(jac == Py_None){ if(odeiv_type == gsl_odeiv_step_bsimp){ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 1); gsl_error("The bsimp method needs a jacobian! You supplied None.", this_file, __LINE__ -2, GSL_EBADFUNC); goto fail; } }else{ if(!PyCallable_Check(jac)){ PyGSL_add_traceback(module, this_file, odeiv_step_init_err_msg, __LINE__ - 1); gsl_error("The jacobian object must be None or callable!", this_file, __LINE__ -2, GSL_EBADFUNC); goto fail; } has_jacobian = 1; } odeiv_step = (PyGSL_odeiv_step *) PyObject_NEW(PyGSL_odeiv_step, &PyGSL_odeiv_step_pytype); if(odeiv_step == NULL){ PyErr_NoMemory(); goto fail; } odeiv_step->step=NULL; odeiv_step->py_func=NULL; odeiv_step->py_jac=NULL; odeiv_step->arguments=NULL; odeiv_step->system.dimension = dim; if(has_jacobian) odeiv_step->system.jacobian = PyGSL_odeiv_jac; else odeiv_step->system.jacobian = NULL; odeiv_step->system.function = PyGSL_odeiv_func; odeiv_step->system.params = (void *) odeiv_step; odeiv_step->step = gsl_odeiv_step_alloc(odeiv_type, dim); if(odeiv_step->step == NULL){ Py_DECREF(odeiv_step); PyErr_NoMemory(); return NULL; } odeiv_step->py_func=func; if(has_jacobian) odeiv_step->py_jac=jac; odeiv_step->arguments = o_params; Py_INCREF(odeiv_step->py_func); Py_INCREF(odeiv_step->arguments); Py_XINCREF(odeiv_step->py_jac); FUNC_MESS_END(); return (PyObject *) odeiv_step; fail: return NULL; }
static int PyGSL_odeiv_jac(double t, const double y[], double *dfdy, double dfdt[], void *params) { int dimension, flag = GSL_FAILURE; PyGSL_odeiv_step *step = NULL; PyGSL_error_info info; PyObject *arglist = NULL, *result = NULL, *tmp=NULL; PyArrayObject *yo = NULL; gsl_vector_view yv, dfdtv; gsl_matrix_view dfdyv; FUNC_MESS_BEGIN(); step = (PyGSL_odeiv_step *) params; if(!PyGSL_ODEIV_STEP_Check(step)){ PyGSL_add_traceback(module, this_file, __FUNCTION__, __LINE__ - 2); gsl_error("Param not a step type!", this_file, __LINE__ -2, GSL_EFAULT); goto fail; } dimension = step->system.dimension; yv = gsl_vector_view_array((double *) y, dimension); yo = PyGSL_copy_gslvector_to_pyarray(&yv.vector); if (yo == NULL) goto fail; arglist = Py_BuildValue("(dOO)", t, yo, step->arguments); assert(step->py_jac); result = PyEval_CallObject(step->py_jac, arglist); info.callback = step->py_jac; info.message = "odeiv_jac"; if((flag = PyGSL_CHECK_PYTHON_RETURN(result, 2, &info)) != GSL_SUCCESS){ goto fail; } info.argnum = 1; tmp = PyTuple_GET_ITEM(result, 0); dfdyv = gsl_matrix_view_array((double *) dfdy, dimension, dimension); if((flag = PyGSL_copy_pyarray_to_gslmatrix(&dfdyv.matrix, tmp, dimension, dimension, &info)) != GSL_SUCCESS){ goto fail; } info.argnum = 2; tmp = PyTuple_GET_ITEM(result, 1); dfdtv = gsl_vector_view_array((double *) dfdt, dimension); if((flag = PyGSL_copy_pyarray_to_gslvector(&dfdtv.vector, tmp, dimension, &info)) != GSL_SUCCESS){ goto fail; } Py_DECREF(arglist); arglist = NULL; Py_DECREF(result); result = NULL; Py_DECREF(yo); yo = NULL; FUNC_MESS_END(); return GSL_SUCCESS; fail: FUNC_MESS("IN Fail"); assert(flag != GSL_SUCCESS); longjmp(step->buffer, flag); return flag; }
/*--------------------------------------------------------------------------- Wrapper functions to push call the approbriate Python Objects ---------------------------------------------------------------------------*/ static int PyGSL_odeiv_func(double t, const double y[], double f[], void *params) { int dimension, flag = GSL_FAILURE; PyObject *arglist = NULL, *result = NULL; PyArrayObject *yo = NULL; PyGSL_odeiv_step * step; gsl_vector_view yv, fv; PyGSL_error_info info; FUNC_MESS_BEGIN(); step = (PyGSL_odeiv_step *) params; if(!PyGSL_ODEIV_STEP_Check(step)){ PyGSL_add_traceback(module, this_file, __FUNCTION__, __LINE__ - 2); gsl_error("Param not a step type!", this_file, __LINE__ -2, GSL_EFAULT); goto fail; } dimension = step->system.dimension; /* Do I need to copy the array ??? */ yv = gsl_vector_view_array((double *) y, dimension); yo = PyGSL_copy_gslvector_to_pyarray(&yv.vector); if (yo == NULL) goto fail; FUNC_MESS("\t\tBuild args"); arglist = Py_BuildValue("(dOO)", t, yo, step->arguments); FUNC_MESS("\t\tEnd Build args"); info.callback = step->py_func; info.message = "odeiv_func"; result = PyEval_CallObject(step->py_func, arglist); if((flag = PyGSL_CHECK_PYTHON_RETURN(result, 1, &info)) != GSL_SUCCESS){ goto fail; } info.argnum = 1; fv = gsl_vector_view_array(f, dimension); if((flag = PyGSL_copy_pyarray_to_gslvector(&fv.vector, result, dimension, &info)) != GSL_SUCCESS){ goto fail; } Py_DECREF(arglist); arglist = NULL; Py_DECREF(yo); yo = NULL; Py_DECREF(result); result = NULL; FUNC_MESS_END(); return GSL_SUCCESS; fail: FUNC_MESS(" IN Fail BEGIN"); Py_XDECREF(yo); Py_XDECREF(result); Py_XDECREF(arglist); FUNC_MESS(" IN Fail END"); assert(flag != GSL_SUCCESS); longjmp(step->buffer, flag); return flag; }