Integral berechnen in C++



  • Hiho
    Wenn ich von einer Funktion das bestimmte Integral in einem Intervall [a,b] berechnen will, dann kann ich ja die Stammfunktion von Hand bestimmen, im Programm-Code eingeben und dann mit der Formel F(b)-F(a) berechnen. Wenn ich nun aber ein Integral habe, von dem ich keine "schöne" Stammfunktion angeben kann, wie berechne ich das dann? Zum Beispiel dieses hier: https://wikimedia.org/api/rest_v1/media/math/render/svg/09c5da35bc1ecbcd1d96dd35670da649636394d4
    Bin ich hier gezwungen die Riemann-Summe zu verwenden? Das möchte ich eigentlich nicht tun, weil das langsam und ungenau ist.
    Danke im Voraus 🙂



  • Hi!

    Es kommt ganz drauf an. Für eindimensionale Integrale kannst du z.B. die Trapez- oder Simpsonregel benutzen (die Error-Bounds sind bekannt). Wenn du mehrdimensionale Integrale berechnen möchtest, sind u.U. Monte-Carlo-Integrationen (z.B. Importance Sampling) besser geeignet.



  • Wenn du an der Anwendung interessiert bist und nicht daran den numerischen Solver selbst zu bauen, würde ich odeint aus boost nehmen.

    Zum Beispiel so:

    #include <cmath>
    #include <iostream>
    #include <boost\numeric\odeint.hpp>
    
    using namespace boost::numeric::odeint;
    
    double Li(double x)
    {
    	auto f = [](double const &, double &dxdt, double t)
    	{
    		dxdt = 1.0 / std::log(t);
    	};
    
    	double result = 0;
    	auto stepper = make_controlled(1.0e-12, 1.0e-12, runge_kutta_dopri5<double>());
    	integrate_adaptive(stepper, f, result, 2.0, x, 1.0e-12);
    
    	return result;
    }
    
    int main()
    {
    	for (double x = 2; x < 10; x += 1)
    	{
    		std::cout << "Li(" << x << ") = " << Li(x) << "\n";
    	}
    }
    

    Ausgabe:

    Li(2) = 0
    Li(3) = 1.11842
    Li(4) = 1.92242
    Li(5) = 2.58942
    Li(6) = 3.17706
    Li(7) = 3.71189
    Li(8) = 4.20855
    Li(9) = 4.67607
    

Anmelden zum Antworten