Integralrechnung (Annäherung) durch Rechtecke (Untersumme)



  • Hallo Forum!

    Also, ich bin wieder dabei bisschen mit C was zu machen und will unter eine Funktion (im Quelltext gegeben) paar Rechtecke (Anzahl durch Benutzer festgelegt) zwischen einem Intervall (auch durch Benutzer festgelegt) legen und die Untersumme der Rechtecke berechnen.
    Wenn ich mein Programm ausführe, kommt immer nur die Breite eines einzelnen Rechtecks raus und ich finde meinen Fehler nicht; ich denke, es ist nur ein kleiner Logikfehler, der schnell zu lösen sein sollte...

    Hier mein Quelltext:

    6 int f(int x);
      7 double square_width(double dist, int amount);
      8
      9 int main(void) {
     10         printf("================\n");
     11         printf("Integralrechnung\n");
     12         printf("================\n\n\n");
     13         double x, y, d, width, xforheight = 0;
     14         int squares, i;
     15         double sum = 0;
     16         printf("Startwert des Intervalls: ");
     17         scanf("%lf", &x);
     18         printf("Endwert des Intervalls: ");
     19         scanf("%lf", &y);
     20         printf("Anzahl Rechtecke: ");
     21         scanf("%d", &squares);
     22         d = y - x;
     23         width = square_width(d, squares);
     24         printf("Das Intervall beträgt %lf.\n", d);
     25         printf("Die Breite eines Rechtecks beträgt %lf.\n", width);
     26         for(i = 0; i < squares; i++) {
     27                 xforheight += width;
     28                 sum += width * f(xforheight);
     29         }
     30         printf("Das Integral der gegebenen Funktion zwischen %lf und %lf ist %lf.\n", x, y, sum);
     31         return 0;
     32 }
     33
     34 int f(int x) {
     35         return pow(x, 2);
     36 }
     37
     38 double square_width(double dist, int amount) {
     39         return (dist/amount);
     40 }
    

    Ich hoffe die Zeilennummern von vim stören nicht all zu sehr...

    Hier die Ausgabe wenn man von x² (die im Quelltext stehende Funktion unter f(x)) von 0 bis 1 mit 5 Rechtecken rechnen will:

    Startwert des Intervalls: 0
    Endwert des Intervalls: 1
    Anzahl Rechtecke: 5
    Das Intervall beträgt 1.000000.
    Die Breite eines Rechtecks beträgt 0.200000.
    Das Integral der gegebenen Funktion zwischen 0.000000 und 1.000000 ist 0.200000.
    

    Hoffentlich findet ihr den Fehler schnell, da ich die fertige Version morgen bräuchte; dafür vielen Dank im Voraus!

    Beste Grüße
    Tw1x



  • Tw1x schrieb:

    6 int f(int x);
    

    Wieso int?



  • Ah, fix...
    immer diese Leichtsinnsfehler -.-

    Dankeschön!
    Jetzt funktioniert es...

    Mein nächster Plan ist jetzt die Obersumme zu berechnen und als Ergebnis den Mittelwert der Ober- und Untersumme auszugeben, da die Fläche dann genauer wird; ich hab nur keinen Plan, wie ich die Obersumme mache.

    Beste Grüße
    Tw1x

    PS: Muss ich für die Obersumme auf der linken Seite des Rechtecks den Funktionswert berechnen...? Also die for-Schleife um die Breite des Rechtecks nach links verschieben...



  • Kannst Du davon ausgehen, dass Deine Funktion monoton steigend ist? Wenn ja, dann ist das genau die richtige Idee. Wenn nein, ist schon Deine Untersumme falsch. (Bei einer monoton fallenden Funktion berechnest Du schon die Obersumme, nicht die Untersumme!)



  • Stimmt. Ist mir grad gekommen...

    Hier hab ich gerade jetzt ne Lösung ausgearbeitet, die bei allen Funktionen funktionieren sollte - SOLLTE (!) - tut es aber nicht.

    Hier mein Code:

    26         for(i = 0; i < squares; i++) {
     27                 xforheight += width;
     28                 rsum += width * f(xforheight);
     29         }
     30         for(i = 0; i < squares; i++) {
     31                 xforheight += width;
     32                 lsum += width * f(xforheight - width);
     33         }
     34         printf("Das Integral von %lf nach %lf über die gegebene Funktion beträgt %lf.\n", x, y, (rsum + lsum)/2);
     35         printf("Rechtecksberechnung Ecke links-oben: %lf\n", lsum);
     36         printf("Rechtecksberechnung Ecke rechts-oben: %lf\n", rsum);
    

    Hier die Ausgabe:

    Startwert des Intervalls: 0
    Endwert des Intervalls: 1
    Anzahl Rechtecke: 10
    Das Intervall beträgt 1.000000.
    Die Breite eines Rechtecks beträgt 0.100000.
    Das Integral von 0.000000 nach 1.000000 über die gegebene Funktion beträgt 1.285000.
    Rechtecksberechnung Ecke links-oben: 2.185000
    Rechtecksberechnung Ecke rechts-oben: 0.385000
    

    Wie auch zuvor gilt es den Fehler zu finden; danke euch im Voraus.

    Beste Grüße
    Tw1x



  • Da fehlt ein

    xforheight = x;
    

    an mehreren Stellen.

    Bzw. würde ich

    xforheight = x + i * width;
    

    nehmen, um Summierungsfehler minimal zu halten.



  • Eine Schleife würde das Problem auch schon lösen:

    xforheight = x;	
    for(i = 0; i < squares; i++) {
      lsum += width * f(xforheight);
      xforheight += width;
      rsum += width * f(xforheight);
    }
    


  • Ok, dankeschön.

    Ich habe jetzt die Lösung mit

    xforheight = x
    

    zusammen mit einer for-Schleife genommen, die funktioniert soweit...

    Wird schon schief gehen morgen^^

    Danke an alle, die mir geholfen haben!

    Beste Grüße
    Tw1x


Anmelden zum Antworten