/* * Author: Andrej Prochazka * Copyright(C) 2017 * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #ifndef INTEGRATOR_H #define INTEGRATOR_H #include "catima/build_config.h" #include "gsl/gsl_integration.h" #include #include #ifdef USE_THREADS #include #endif namespace catima{ /// helper class to integrate functions using the GSL library class IntegratorGSL{ public: IntegratorGSL(bool adapt=true); ~IntegratorGSL(); double integrate(std::function f, double min, double max, double precision=0.001); private: gsl_integration_workspace *w; bool adaptive; double error; double result; double min; double max; #ifdef USE_THREADS std::mutex integration_mutex; #endif }; // built in integrator template class GaussLegendreIntegration{ public: template double integrate(F f, double a, double b) const; template double operator()(F f, double a, double b) const {return integrate(f, a, b);} double get_w(int i) const {return w[i];} double get_x(int i) const {return x[i];} int n() const {return order;} std::array get_points(double a = -1.0, double b = 1.0)const; public: static std::array w; static std::array x; }; template template double GaussLegendreIntegration::integrate(F f, double a, double b) const{ double res=0.0; double p = 0.5*(b-a); double q = 0.5*(b+a); for(int i=0;i std::array GaussLegendreIntegration::get_points(double a, double b)const{ std::array points; double p = 0.5*(b-a); double q = 0.5*(b+a); int num = (order/2); for(int i=0;i< num;i++){ points[num-i-1] = -p*x[i] + q; points[num+i] = p*x[i] + q; } return points; } #ifdef GSL_INTEGRATION using integrator_type = IntegratorGSL; #else using integrator_type = GaussLegendreIntegration<8>; #endif extern integrator_type integrator; extern IntegratorGSL integratorGSL; } #endif