Trapez-Integration, Romberg-Verfahren



  • Hallo!

    Eine Aufgabe meines C++ Kurses, Trapez-Integration, Romberg-Verfahren..

    ..eigentlich habe ich die Aufgabe gelöst, ich habe nur ein kleines Problem, die genauigkeit!

    folgender Code :

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <new>
    
    using namespace std;
    
    //_________________________________Funktionen für Integration___________________________________//
    
    //Integrier Klasse
    class integ
    {
    //__________________________________________________Private
        private:
    
        double a;
        double b;
    
        //Übernahme der Funktion FUNKTIONIERT!
        void (*P)(double&);
        double f(double x,void (*pt2Func)(double&)) {pt2Func(x);return(x);}
    
        //Funktionswert an der Stelle j FUNKTIONIERT!
        double F_j (double j,double N) {return(f(a+j*(b-a)/N,P));}
    
        //Trapezsumme FUNKTIONIERT!
        double Ftr_N (double N)
        {
            double Sum=F_j(0,N)+F_j(N,N);
            for (int i=1;i<N;i++) Sum+=(2*F_j(i,N));
            Sum *= (b-a)/(N*2);
            //cout << "\n N:" << N << " Sum" << Sum;
            return(Sum);
        }
    
        //Interpolation
        double ipol(double Pio[] ,int Len=0)
        {
    
            cout << "\n\n";
            long FOR=4;
    
            //Ausgabe der ersten Zeile
            for (int j=Len-1;j>=0;j--) cout << setw(3) << "[" << j << ".0]" << setprecision(4) << setw(5) << Pio[j];
            cout << "\n";
    
            //Interpolierter Wert
    		for (int h=1;h<Len;h++) {
    			for (int j=Len-1;j>=h;j--) {
    				Pio[j]=Pio[j]+(Pio[j]-Pio[j-1])/(FOR-1);
    				cout << setw(3) << "[" << j << "." << h << "]" << setprecision(3) << setw(5) << Pio[j];
    			}
    			FOR*=4;
    			cout << "\n";
    		}
    
            return(Pio[Len-1]);
            //return(0);
        }
    
        //Eigentliche Integration
        double intgr()
        {
            const double e=1E-4;
            int i=2;
            double T=0;
            double G=Ftr_N(1);
    
            //ermittle N oder auch i max
            for (;abs((G-T)/G)>e and i<10/*65536*/;i*=2)
            {
                T=G;
                G=Ftr_N(i);
            }
    
            //erstelle die Pio in einem Array
            i++; //i intervalle, aber i+1 Stützstellen
            double Pio[i];
            for (int j=1;j<i;j++)
            {
                Pio[j]=Ftr_N(2*j);
            }
            Pio[0]=0;//dieser Wert ändert NIX! ..ob 100 oder 200.. völlig egal
            //Romberg interpolation
            double xpol = ipol(Pio,i);
    
            return (xpol);
    
        }
    //__________________________________________________Public
        public:
    
        //Konstruktor
        integ(void (*pt2Func)(double&),double A=0,double B=0)
        {
            P = *pt2Func;
            a=A;
            b=B;
        }
    
        //Ausgabe
        void Solve()
        {
            cout << "\n Integration von f auf dem Intervall [ " << a << " ; " << b << " ] ergibt S = " << setprecision(10) << intgr();
        }
    
    };
    
    //_________________________________Main___________________________________//
    
    //Die Funktion über die integriert wird
    void f(double &x) {x=sqrt(x)/(1+x*x);}
    
    //void f(double &x) {x=x*x;} //Testfunktion
    
    int main()
    {
        int a=0,b=10;
        cout << "\n 1) Trapez-Integration, Romberg-Verfahren : \n";
    
        integ INT(f,a,b);
        INT.Solve();
    
        cout << "\n\n";
        return(0);
    }
    

    Die verwendete Funktion f(x) = sqrt(x)/(1+x²) solte von 0 bis 10 integriert ungefähr 1,590243869 ergeben! ich kriege mit meinem Code aber nur 1.551838253!

    ..ich habe absolut keinen Plan wo der Fehler liegt, vielleicht ist das Verfahren auch nicht so präzise, aber schließlich hat man uns ja so viele Stellen nach dem Komma gegeben..

    Ich hab schon ziemlich alles nachgerechnet, teilweise per Hand, und keinen Fehler gefunden 😞

    HILFE!! x)

    danke für eure Zeit 🙂

    Victor



  • ich hab' jetzt keine lust, das ganze auseinanderzufrickeln. aber zwei tipps:

    - schau dir, wie der wert mit steigendem N konvergiert (oder auch nicht)
    also N = 2,20,200,2000... und dann differenz zum exakten wert plotten. bei deinem integrationsverfahren sollte ja eine konvergenzgeschwindigkeit angegeben sein
    - löse ein paar trivial integrierbare probleme (f(x)=1, x^n, exp(x)) u.s.w. dann siehst du vielleicht den fehler.

    //Die Funktion über die integriert wird
    void f(double &x) {x=sqrt(x)/(1+x*x);}
    

    warum verwendest du nicht

    //Die Funktion über die integriert wird
    double f(double x) {return sqrt(x)/(1+x*x);}
    

    dann kannst du dir auch integ::f(...) sparen?



  • EDIT 2 : gelößt! (kann man den thread damit markieren?) die FOR variable muss als datantyp long double haben! dann gehts 🙂

    EDIT : liegt wohl an der 4^k in der Extrapolation, die wird sehr schnell viel zu groß und wird somit 0.. muss die extrapolation anders berechnen.

    Danke für deine Antwort,

    das mit der Funktion hab ich geändert, hatte es anders gemacht am anfang da F_j jetzt einen Parameter mehr hat aber egal, so spare ich immerhin eine Funktion _

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <new>
    
    using namespace std;
    
    //_________________________________Funktionen für Integration___________________________________//
    
    //Integrier Klasse
    class integ
    {
    //__________________________________________________Private
        private:
    
        double a;
        double b;
    
        //Übernahme der Funktion FUNKTIONIERT!
        double (*P)(double);
    
        //Funktionswert an der Stelle j FUNKTIONIERT!
        double F_j (double j,double N,double (*pt2Func)(double)) {return(pt2Func(a+j*(b-a)/N));}
    
        //Trapezsumme FUNKTIONIERT!
        double Ftr_N (double N)
        {
            double Sum=F_j(0,N,P)+F_j(N,N,P);
            for (int i=1;i<N;i++) Sum+=(2*F_j(i,N,P));
            Sum *= (b-a)/(N*2);
            cout << "\n N:" << N << " Sum" << Sum;
            return(Sum);
        }
    
        //Interpolation
        double ipol(double Pio[] ,int Len=0)
        {
    
            cout << "\n\n";
            long FOR=4;
    
            //Ausgabe der ersten Zeile
            //for (int j=Len-1;j>=0;j--) cout << setw(3) << "[" << j << ".0]" << setprecision(4) << setw(5) << Pio[j];
            cout << "\n";
    
            //Interpolierter Wert
    		for (int h=1;h<Len;h++) {
    			for (int j=Len-1;j>=h;j--) {
    				Pio[j]=Pio[j]+(Pio[j]-Pio[j-1])/(FOR-1);
    				//cout << setw(3) << "[" << j << "." << h << "]" << setprecision(3) << setw(5) << Pio[j];
    			}
    			FOR*=4;
    			//cout << "\n";
    		}
    
            return(Pio[Len-1]);
            //return(0);
        }
    
        //Eigentliche Integration
        double intgr()
        {
            const double e=1E-4;
            int i=2;
            double T=0;
            double G=Ftr_N(1);
    
            //ermittle N oder auch i max
            for (;abs((G-T)/G)>e and i<1000/*65536*/;i*=2)
            {
                T=G;
                G=Ftr_N(i);
            }
    
            //erstelle die Pio in einem Array
            i++; //i intervalle, aber i+1 Stützstellen
            double Pio[i];
            for (int j=1;j<i;j++)
            {
                Pio[j]=Ftr_N(2*j);
            }
            Pio[0]=0;//dieser Wert ändert NIX! ..ob 100 oder 200.. völlig egal
            //Romberg interpolation
            double xpol = ipol(Pio,i);
    
            return (xpol);
    
        }
    //__________________________________________________Public
        public:
    
        //Konstruktor
        integ(double (*pt2Func)(double),double A=0,double B=0)
        {
            P = *pt2Func;
            a=A;
            b=B;
        }
    
        //Ausgabe
        void Solve()
        {
            cout << "\n Integration von f auf dem Intervall [ " << a << " ; " << b << " ] ergibt S = " << setprecision(10) << intgr();
        }
    
    };
    
    //_________________________________Main___________________________________//
    
    //Die Funktion über die integriert wird
    double f(double x) {return sqrt(x)/(1+x*x);}
    
    //void f(double &x) {x=x*x;} //Testfunktion
    
    int main()
    {
        int a=0,b=10;
        cout << "\n 1) Trapez-Integration, Romberg-Verfahren : \n";
    
        integ INT(f,a,b);
        INT.Solve();
    
        cout << "\n\n";
        return(0);
    }
    

    Also die Trapezsummen konvergieren für N -> ∞ gegen den richtigen Wert, das funktioniert anscheinend sehr genau, aber den Wert nehme ich ja nur als erste Zeile im Tableau der Extrapolation.

    Der per Extrapolation berechnete Wert konvergiert jedoch gegen den Falschen Wert 😞

    Mit einfachen Funktion (1 x x² ..) merkt man davon nichts, erst bei Funktion mit mehreren Termen wie x²+3 +x

    So verhält sich die letzte Zeile meines tableaus für ein relativ kleinen N, der letzte Wert müsste der gesuchten Integration entsprechen.

    [512.6] 1.59
    [512.7] 1.59
    [512.8] 1.59
    [512.9] 1.59
    [512.10] 1.59
    [512.11] 1.59
    [512.12] 1.59
    [512.13] 1.59
    [512.14] 1.59
    [512.15] 1.59
    [512.16] 1.59
    [512.17] 1.59
    [512.18] 1.59
    [512.19] 1.59
    [512.20] 1.59
    [512.21] 1.59
    [512.22] 1.59
    [512.23] 1.59
    [512.24] 1.59
    [512.25] 1.59
    [512.26] 1.59
    [512.27] 1.59
    [512.28] 1.59
    [512.29] 1.59
    [512.30] 1.59
    [512.31] 1.59
    [512.32] 1.59
    [512.33] 1.59
    [512.34] 1.59
    [512.35] 1.59
    [512.36] 1.59
    [512.37] 1.59
    [512.38] 1.59
    [512.39] 1.59
    [512.40] 1.59
    [512.41] 1.59
    [512.42] 1.59
    [512.43] 1.59
    [512.44] 1.59
    [512.45] 1.59
    [512.46] 1.59
    [512.47] 1.59
    [512.48] 1.59
    [512.49] 1.59
    [512.50] 1.59
    [512.51] 1.59
    [512.52] 1.59
    [512.53] 1.59
    [512.54] 1.59
    [512.55] 1.59
    [512.56] 1.59
    [512.57] 1.59
    [512.58] 1.59
    [512.59] 1.59
    [512.60] 1.59
    [512.61] 1.59
    [512.62] 1.59
    [512.63] 1.59
    [512.64] 1.59
    [512.65] 1.59
    [512.66] 1.59
    [512.67] 1.59
    [512.68] 1.59
    [512.69] 1.59
    [512.70] 1.59
    [512.71] 1.59
    [512.72] 1.59
    [512.73] 1.59
    [512.74] 1.59
    [512.75] 1.59
    [512.76] 1.59
    [512.77] 1.59
    [512.78] 1.59
    [512.79] 1.59
    [512.80] 1.59
    [512.81] 1.59
    [512.82] 1.59
    [512.83] 1.59
    [512.84] 1.59
    [512.85] 1.59
    [512.86] 1.59
    [512.87] 1.59
    [512.88] 1.59
    [512.89] 1.59
    [512.90] 1.59
    [512.91] 1.59
    [512.92] 1.59
    [512.93] 1.59
    [512.94] 1.59
    [512.95] 1.59
    [512.96] 1.59
    [512.97] 1.59
    [512.98] 1.59
    [512.99] 1.59
    [512.100] 1.59
    [512.101] 1.59
    [512.102] 1.59
    [512.103] 1.59
    [512.104] 1.59
    [512.105] 1.59
    [512.106] 1.59
    [512.107] 1.59
    [512.108] 1.59
    [512.109] 1.59
    [512.110] 1.59
    [512.111] 1.59
    [512.112] 1.59
    [512.113] 1.59
    [512.114] 1.59
    [512.115] 1.59
    [512.116] 1.59
    [512.117] 1.59
    [512.118] 1.59
    [512.119] 1.59
    [512.120] 1.59
    [512.121] 1.59
    [512.122] 1.59
    [512.123] 1.59
    [512.124] 1.59
    [512.125] 1.59
    [512.126] 1.59
    [512.127] 1.59
    [512.128] 1.59
    [512.129] 1.59
    [512.130] 1.59
    [512.131]1.5899
    [512.132]1.5899
    [512.133]1.5899
    [512.134]1.5899
    [512.135]1.5899
    [512.136]1.5899
    [512.137]1.5899
    [512.138]1.5899
    [512.139]1.5899
    [512.140]1.5899
    [512.141]1.5899
    [512.142]1.5899
    [512.143]1.5899
    [512.144]1.5899
    [512.145]1.5899
    [512.146]1.5899
    [512.147]1.5899
    [512.148]1.5899
    [512.149]1.5899
    [512.150]1.5899
    [512.151]1.5899
    [512.152]1.5899
    [512.153]1.5899
    [512.154]1.5899
    [512.155]1.5899
    [512.156]1.5899
    [512.157]1.5899
    [512.158]1.5899
    [512.159]1.5899
    [512.160]1.5899
    [512.161]1.5899
    [512.162]1.5899
    [512.163]1.5899
    [512.164]1.5899
    [512.165]1.5899
    [512.166]1.5899
    [512.167]1.5899
    [512.168]1.5899
    [512.169]1.5899
    [512.170]1.5899
    [512.171]1.5899
    [512.172]1.5899
    [512.173]1.5899
    [512.174]1.5899
    [512.175]1.5899
    [512.176]1.5899
    [512.177]1.5899
    [512.178]1.5899
    [512.179]1.5899
    [512.180]1.5899
    [512.181]1.5899
    [512.182]1.5899
    [512.183]1.5899
    [512.184]1.5899
    [512.185]1.5899
    [512.186]1.5899
    [512.187]1.5899
    [512.188]1.5899
    [512.189]1.5899
    [512.190]1.5899
    [512.191]1.5899
    [512.192]1.5899
    [512.193]1.5899
    [512.194]1.5899
    [512.195]1.5899
    [512.196]1.5899
    [512.197]1.5899
    [512.198]1.5899
    [512.199]1.5899
    [512.200]1.5899
    [512.201]1.5898
    [512.202]1.5898
    [512.203]1.5898
    [512.204]1.5898
    [512.205]1.5898
    [512.206]1.5898
    [512.207]1.5898
    [512.208]1.5898
    [512.209]1.5898
    [512.210]1.5898
    [512.211]1.5898
    [512.212]1.5898
    [512.213]1.5898
    [512.214]1.5898
    [512.215]1.5898
    [512.216]1.5898
    [512.217]1.5898
    [512.218]1.5898
    [512.219]1.5898
    [512.220]1.5898
    [512.221]1.5898
    [512.222]1.5898
    [512.223]1.5898
    [512.224]1.5898
    [512.225]1.5898
    [512.226]1.5898
    [512.227]1.5898
    [512.228]1.5898
    [512.229]1.5898
    [512.230]1.5898
    [512.231]1.5898
    [512.232]1.5898
    [512.233]1.5898
    [512.234]1.5898
    [512.235]1.5898
    [512.236]1.5898
    [512.237]1.5898
    [512.238]1.5898
    [512.239]1.5898
    [512.240]1.5898
    [512.241]1.5898
    [512.242]1.5898
    [512.243]1.5898
    [512.244]1.5898
    [512.245]1.5898
    [512.246]1.5898
    [512.247]1.5897
    [512.248]1.5897
    [512.249]1.5897
    [512.250]1.5897
    [512.251]1.5897
    [512.252]1.5897
    [512.253]1.5897
    [512.254]1.5897
    [512.255]1.5897
    [512.256]1.5897
    [512.257]1.5897
    [512.258]1.5897
    [512.259]1.5897
    [512.260]1.5897
    [512.261]1.5897
    [512.262]1.5897
    [512.263]1.5897
    [512.264]1.5897
    [512.265]1.5897
    [512.266]1.5897
    [512.267]1.5897
    [512.268]1.5897
    [512.269]1.5897
    [512.270]1.5897
    [512.271]1.5897
    [512.272]1.5897
    [512.273]1.5897
    [512.274]1.5897
    [512.275]1.5897
    [512.276]1.5897
    [512.277]1.5897
    [512.278]1.5897
    [512.279]1.5897
    [512.280]1.5896
    [512.281]1.5896
    [512.282]1.5896
    [512.283]1.5896
    [512.284]1.5896
    [512.285]1.5896
    [512.286]1.5896
    [512.287]1.5896
    [512.288]1.5896
    [512.289]1.5896
    [512.290]1.5896
    [512.291]1.5896
    [512.292]1.5896
    [512.293]1.5896
    [512.294]1.5896
    [512.295]1.5896
    [512.296]1.5896
    [512.297]1.5896
    [512.298]1.5896
    [512.299]1.5896
    [512.300]1.5896
    [512.301]1.5896
    [512.302]1.5896
    [512.303]1.5896
    [512.304]1.5895
    [512.305]1.5895
    [512.306]1.5895
    [512.307]1.5895
    [512.308]1.5895
    [512.309]1.5895
    [512.310]1.5895
    [512.311]1.5895
    [512.312]1.5895
    [512.313]1.5895
    [512.314]1.5895
    [512.315]1.5895
    [512.316]1.5895
    [512.317]1.5895
    [512.318]1.5895
    [512.319]1.5895
    [512.320]1.5895
    [512.321]1.5895
    [512.322]1.5895
    [512.323]1.5894
    [512.324]1.5894
    [512.325]1.5894
    [512.326]1.5894
    [512.327]1.5894
    [512.328]1.5894
    [512.329]1.5894
    [512.330]1.5894
    [512.331]1.5894
    [512.332]1.5894
    [512.333]1.5894
    [512.334]1.5894
    [512.335]1.5894
    [512.336]1.5894
    [512.337]1.5894
    [512.338]1.5894
    [512.339]1.5893
    [512.340]1.5893
    [512.341]1.5893
    [512.342]1.5893
    [512.343]1.5893
    [512.344]1.5893
    [512.345]1.5893
    [512.346]1.5893
    [512.347]1.5893
    [512.348]1.5893
    [512.349]1.5893
    [512.350]1.5893
    [512.351]1.5893
    [512.352]1.5892
    [512.353]1.5892
    [512.354]1.5892
    [512.355]1.5892
    [512.356]1.5892
    [512.357]1.5892
    [512.358]1.5892
    [512.359]1.5892
    [512.360]1.5892
    [512.361]1.5892
    [512.362]1.5892
    [512.363]1.5891
    [512.364]1.5891
    [512.365]1.5891
    [512.366]1.5891
    [512.367]1.5891
    [512.368]1.5891
    [512.369]1.5891
    [512.370]1.5891
    [512.371]1.5891
    [512.372]1.589
    [512.373]1.589
    [512.374]1.589
    [512.375]1.589
    [512.376]1.589
    [512.377]1.589
    [512.378]1.589
    [512.379]1.589
    [512.380]1.5889
    [512.381]1.5889
    [512.382]1.5889
    [512.383]1.5889
    [512.384]1.5889
    [512.385]1.5889
    [512.386]1.5889
    [512.387]1.5888
    [512.388]1.5888
    [512.389]1.5888
    [512.390]1.5888
    [512.391]1.5888
    [512.392]1.5888
    [512.393]1.5888
    [512.394]1.5887
    [512.395]1.5887
    [512.396]1.5887
    [512.397]1.5887
    [512.398]1.5887
    [512.399]1.5886
    [512.400]1.5886
    [512.401]1.5886
    [512.402]1.5886
    [512.403]1.5886
    [512.404]1.5885
    [512.405]1.5885
    [512.406]1.5885
    [512.407]1.5885
    [512.408]1.5885
    [512.409]1.5884
    [512.410]1.5884
    [512.411]1.5884
    [512.412]1.5884
    [512.413]1.5883
    [512.414]1.5883
    [512.415]1.5883
    [512.416]1.5883
    [512.417]1.5882
    [512.418]1.5882
    [512.419]1.5882
    [512.420]1.5882
    [512.421]1.5881
    [512.422]1.5881
    [512.423]1.5881
    [512.424]1.588
    [512.425]1.588
    [512.426]1.588
    [512.427]1.5879
    [512.428]1.5879
    [512.429]1.5879
    [512.430]1.5878
    [512.431]1.5878
    [512.432]1.5877
    [512.433]1.5877
    [512.434]1.5877
    [512.435]1.5876
    [512.436]1.5876
    [512.437]1.5875
    [512.438]1.5875
    [512.439]1.5874
    [512.440]1.5874
    [512.441]1.5873
    [512.442]1.5873
    [512.443]1.5872
    [512.444]1.5872
    [512.445]1.5871
    [512.446]1.5871
    [512.447]1.587
    [512.448]1.587
    [512.449]1.5869
    [512.450]1.5868
    [512.451]1.5868
    [512.452]1.5867
    [512.453]1.5866
    [512.454]1.5865
    [512.455]1.5865
    [512.456]1.5864
    [512.457]1.5863
    [512.458]1.5862
    [512.459]1.5861
    [512.460]1.586
    [512.461]1.5859
    [512.462]1.5858
    [512.463]1.5857
    [512.464]1.5856
    [512.465]1.5855
    [512.466]1.5854
    [512.467]1.5853
    [512.468]1.5852
    [512.469]1.585
    [512.470]1.5849
    [512.471]1.5848
    [512.472]1.5846
    [512.473]1.5845
    [512.474]1.5843
    [512.475]1.5841
    [512.476]1.5839
    [512.477]1.5837
    [512.478]1.5836
    [512.479]1.5833
    [512.480]1.5831
    [512.481]1.5829
    [512.482]1.5826
    [512.483]1.5824
    [512.484]1.5821
    [512.485]1.5818
    [512.486]1.5815
    [512.487]1.5812
    [512.488]1.5808

    [512.489]1.5805
    [512.490]1.5801
    [512.491]1.5797
    [512.492]1.5792
    [512.493]1.5787
    [512.494]1.5782
    [512.495]1.5776
    [512.496]1.577
    [512.497]1.5764
    [512.498]1.5757
    [512.499]1.5749
    [512.500]1.574
    [512.501]1.5731
    [512.502]1.5721
    [512.503]1.571
    [512.504]1.5697
    [512.505]1.5683
    [512.506]1.5668
    [512.507]1.565
    [512.508]1.5631
    [512.509]1.5608
    [512.510]1.5583
    [512.511]1.5553
    [512.512]1.5518

    Integration von f auf dem Intervall [ 0 ; 10 ] ergibt S = 1.551838253

    gibt es eine möglichkeit so eine lange liste so zu posten das man das auf und zuklappen kann? ..so wie etwa ein spoiler ..nur um platz zu sparen


Anmelden zum Antworten