[C++] Całkowanie numeryczne

Awatar użytkownika
Hajtowy
Użytkownik
Użytkownik
Posty: 754
Rejestracja: 12 wrz 2010, o 10:47
Płeć: Mężczyzna
Lokalizacja: PL
Podziękował: 213 razy
Pomógł: 5 razy

[C++] Całkowanie numeryczne

Post autor: Hajtowy »

Witam!

Mam napisać program w C++ Builder 6.

Napisz program obliczający pole pod wykresem funkcji \(\displaystyle{ y=x^2+4}\) metodą prostokątów oraz trapezów dla przedziału \(\displaystyle{ \left\langle 0;10\right\rangle}\) z dokładnością \(\displaystyle{ 0,1}\)

METODA TRAPEZÓW :

Kod: Zaznacz cały

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

float func(float x)
{
return (x*x+4);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float xp, xk, dx, calka;
int i, n;
n = 100;
xp = 0 ;
xk = 10;
calka = 0;
dx = (xk - xp) / n;
for (i=1; i<=n; i++)
{
 calka += func(xp + i * dx);
 calka = (calka + (func(xp) + func(xk)) / 2) * dx;
}
calka *= dx;
Form1->Edit1->Text = calka;
Form1->Edit1->Text=AnsiString().FormatFloat("0.#", calka); //zaokraglanie do 1 miejsca po przecinku
}
//---------------------------------------------------------------------------
Co tutaj jest źle, że zamiast \(\displaystyle{ 373,3}\) wyświetla mi \(\displaystyle{ 1,8}\) ?

Jak dodać żeby tylko wyświetlało 1 liczbę po przecinku i jak naprawić ten program, żeby działał poprawnie?
pawellogrd
Użytkownik
Użytkownik
Posty: 844
Rejestracja: 19 lis 2009, o 15:03
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 121 razy
Pomógł: 156 razy

[C++] Całkowanie numeryczne

Post autor: pawellogrd »

Linia 34 - nie powinna się znaleźć w pętli tylko poza nią, a linii 36 w ogóle nie powinno być czyli zamiast:

Kod: Zaznacz cały

for (i=1; i<=n; i++)
{
 calka += func(xp + i * dx);
 calka = (calka + (func(xp) + func(xk)) / 2) * dx;
}
calka *= dx;
powinno być:

Kod: Zaznacz cały

for (i=1; i<=n; i++)
{
 calka += func(xp + i * dx);
}
calka = (calka + (func(xp) + func(xk)) / 2) * dx;
Po tej modyfikacji powinno zadziałać.
Awatar użytkownika
Hajtowy
Użytkownik
Użytkownik
Posty: 754
Rejestracja: 12 wrz 2010, o 10:47
Płeć: Mężczyzna
Lokalizacja: PL
Podziękował: 213 razy
Pomógł: 5 razy

[C++] Całkowanie numeryczne

Post autor: Hajtowy »

pawellogrd, tak, działa

Wynik wychodzi : \(\displaystyle{ 383,8}\) i to jest do metody prostokątów czy trapezów ?
pawellogrd
Użytkownik
Użytkownik
Posty: 844
Rejestracja: 19 lis 2009, o 15:03
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 121 razy
Pomógł: 156 razy

[C++] Całkowanie numeryczne

Post autor: pawellogrd »

Mały błąd. Jeżeli to ma być metoda trapezów to sumujesz nie do \(\displaystyle{ n}\) tylko do \(\displaystyle{ n-1}\), a więc zamiast

Kod: Zaznacz cały

for (i=1; i<=n; i++)
powinno być

Kod: Zaznacz cały

for (i=1; i<n; i++)
, co akurat tutaj raczej nie zmieni wyniku skoro obliczamy z dokładnością do pierwszego miejsca po przecinku. Na końcu dodajesz do obliczanej wartości \(\displaystyle{ \frac{f(x_p)+f(x_k)}{2}}\), co jednoznacznie już wskazuje na metodę trapezów.
Awatar użytkownika
Hajtowy
Użytkownik
Użytkownik
Posty: 754
Rejestracja: 12 wrz 2010, o 10:47
Płeć: Mężczyzna
Lokalizacja: PL
Podziękował: 213 razy
Pomógł: 5 razy

[C++] Całkowanie numeryczne

Post autor: Hajtowy »

Dużo się zmieni w kodzie do metody prostokątów?

Wynik do metody trapezów wygląda następująco :

Do 1 miejsca po przecinku : \(\displaystyle{ 373,4}\)
Do 2 miejsc po przecinku : \(\displaystyle{ 373,35}\)
pawellogrd
Użytkownik
Użytkownik
Posty: 844
Rejestracja: 19 lis 2009, o 15:03
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 121 razy
Pomógł: 156 razy

[C++] Całkowanie numeryczne

Post autor: pawellogrd »

Niewiele, ale trochę tak, zajrzyj na wzór, który podałem Ci w innym temacie.
Awatar użytkownika
Hajtowy
Użytkownik
Użytkownik
Posty: 754
Rejestracja: 12 wrz 2010, o 10:47
Płeć: Mężczyzna
Lokalizacja: PL
Podziękował: 213 razy
Pomógł: 5 razy

[C++] Całkowanie numeryczne

Post autor: Hajtowy »

Zrobiłem to następująco, ale wynik mi się coś nie zgadza...

Kod: Zaznacz cały

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

float func(float x)
{
return (x*x+4);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float xp, xk, dx, calka;
int i, n;
n = 100;
xp = 0 ;
xk = 10;
dx = (xk - xp) / n;
for (i=1; i<n; i++)
{
 calka += func(xp + i * dx);
}
calka = dx * calka * (func(xp) + func(xk) / 2);
Form1->Edit1->Text = calka;
Form1->Edit1->Text=AnsiString().FormatFloat("0.##", calka); // ## (2) miejsca po przecinku
}
//---------------------------------------------------------------------------
Skorzystałem ze wzoru :

\(\displaystyle{ s_i=d \cdot y_i = d \cdot f \left( \frac{x_{i-1}+x_{i}}{2}\right)}\)
pawellogrd
Użytkownik
Użytkownik
Posty: 844
Rejestracja: 19 lis 2009, o 15:03
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 121 razy
Pomógł: 156 razy

[C++] Całkowanie numeryczne

Post autor: pawellogrd »

Linia 30 - w metodzie prostokątów sumujesz do \(\displaystyle{ n}\), a więc tutaj będzie właśnie for (i=1; i<=n; i++) zamiast for (i=1; i<n; i++)

Linia 34 - w metodzie prostokątów nie dodajesz już wartości ułamka, który podałem wcześniej, więc zamiast calka = dx * calka * (func(xp) + func(xk) / 2); tutaj będziesz miał calka *= dx;

Poza tym brakuje Ci ustawienia początkowej wartości zmiennej calka na zero, przez co dostaniesz prawdopodobnie NaN.
Awatar użytkownika
Hajtowy
Użytkownik
Użytkownik
Posty: 754
Rejestracja: 12 wrz 2010, o 10:47
Płeć: Mężczyzna
Lokalizacja: PL
Podziękował: 213 razy
Pomógł: 5 razy

[C++] Całkowanie numeryczne

Post autor: Hajtowy »

Oke Działa

Wynik : \(\displaystyle{ 378,35}\)

Dzięki !
pawellogrd
Użytkownik
Użytkownik
Posty: 844
Rejestracja: 19 lis 2009, o 15:03
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 121 razy
Pomógł: 156 razy

[C++] Całkowanie numeryczne

Post autor: pawellogrd »

Polecam jeszcze zwiększyć trochę \(\displaystyle{ n}\) przynajmniej do \(\displaystyle{ 500}\), powinno dać nieco lepszy wynik.
Awatar użytkownika
Hajtowy
Użytkownik
Użytkownik
Posty: 754
Rejestracja: 12 wrz 2010, o 10:47
Płeć: Mężczyzna
Lokalizacja: PL
Podziękował: 213 razy
Pomógł: 5 razy

[C++] Całkowanie numeryczne

Post autor: Hajtowy »

Już działa poprawnie, tak jak należy

Dzięki wielkie za pomoc
ODPOWIEDZ