határozott integrál C-ben

 ( applebred | 2008. február 27., szerda - 17:04 )

Üdv!

Határozott integrált szeretnék leprogramozni C-ben.
Az integrál: T = 100*integrál[0-tól 52.4-ig](dx /(1.1*x^2))
Az eredmény, aminek kikéne jönni : 374.78
Módszer: téglalapokkal közelítem a görbe alatti területet.

Amire eddig jutottam:

#include <stdio.h>

int main() {

	int a=0, b=52,op=1000, i=0;
	float da, db, dx;
	float alsoosszeg = 0;
	float felsoosszeg = 0;

	dx = (float)(b-a)/op;

	for (i=1; i<op; i++) {
	da = a + (i*dx);
	db = a + ((i+1)*dx);
	alsoosszeg+= dx*(1/(1.1*da*da)); // itt szamolja a fuggvenyerteket
	felsoosszeg+= dx*(1/(1.1*db*db)); // ez most az 1/(1.1*x^2) fuggveny
	}
	alsoosszeg=alsoosszeg*100;
	felsoosszeg=felsoosszeg*100;

	printf("Az also kozelito osszeg: %f\n",alsoosszeg);
	printf("A felso kozelito osszeg: %f\n",felsoosszeg);
}

A program lefordul, működik, csak nem jól. :)
Fordítás linux alatt: gcc -o int int.c , ha int.c -be van mentve a kód.

Mit rontok el? (az is lehet, hogy az egész rossz)

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

ezzel a fuggvennyel vigyazni kell, ugyanis 0 -ban 1/(1.1*x^2) az bizony nulla.

ha jol latom, a fuggvenybol az 1/1.1 kiemelheto konstans tag, igy marad integral 1/x^2, ami ugye integral x^-2, ami ugye -x^-1;

namost 100/1.1 * integral 0tol 52.4ig x^-2 = 100/1.1 * -52.4^-1, ami szereny szamitasaim szerint -1.7175572460 koruli ertek...

Az a deriváltja lesz, nem?

KisKresz

Nem, az nem a deriváltja:

int(x^n)dx=x^(n+1)/(n+1)+c (n<>-1),
valamint -2+1=-1 ;-)

Affene! Lebuktam, milyen régen is volt a matekóra! :-)

KisKresz

+1
Nekem is végtelen improprius integrálnak tűnik. A 0-ban baj van.

integrate(1/(x*x),x,0,52);

Integral is divergent -- an error.
To debug this try debugmode(true);

Nullaval osztani nehez..

igen,igen,így van :)
Nullával osztani tényleg nehéz, ez nekem is leesett, mert a for ciklus is eredetileg nulláról indult, nem egyről.
Kiszámoltam énis, nekemis -1,7349 körül jön ki, az eredményt készen kaptam:S

De akkor hogy csináljam?
Arra is gondoltam, hogy ne nullától kezdjem az integrálást, hanem mondjuk 0,0001 -től, hisz úgyis csak közelítő értéket kapok?

Nem érted a probléma lényegét.

Nem az a gond, hogy a for ciklus eredetileg 0-ról indult. Az 1/(gyök x) -et ki lehet integrálni 0-tól 1-ig, pedig abban is nullával kellene osztani az algoritmusod első lépésénél.

A gond az, hogy nem értelmes a kérdés. Ez egy végtelen improprius integrál. Ha epszilon-tól integrálod mondjuk 1-ig, akkor epszilont csökkentve bármilyen nagy lehet. A 0-ban probléma van, de ez nem oldható meg például azzal, hogy a 0 egy kis környezetét kiszedjük.

Leginkabb elvi problemaim vannak a dologgal. Regen volt mar analizis ora, de ha a problemat megprobalom papiron megoldani (attol meg, hogy a szamitogep okos, nekunk nem kell hulyenek lenni) nekem nem franko.

Szoval az f=1/(1.1*x*x) primitiv fuggvenye szerintem F=1/(-1.1*x). Namost elvileg F(b)-F(a) az a hatarozott integral, ami neked kell. Jol latszik, hogy 0-ra nincs ertelmezve. Ha lerajzolod a fuggvenyt, akkor szerintem eleg egyertelmu, hogy miert (0 korul elszall az f fuggveny +/- vegtelen fele). Eleg szerencsetlenul probaltad ezt a tenyt kicselezni a programban (nem teljesen gombolyuek az also es felso kozelito osszegek). Meg mielott megprobalod tovabb csavarni a dolgot az a ertek nagyon kicsi nem nulla ertekre allitasaval, ne tedd, mert ott meg a float nem fogja birni a gyurodest. De abban az esetben meg brutalis integralok jonnek majd ki.

Mindenkinek igaza van..:)
Rosszul kaptam meg a feladatot, mint kiderült. Egy szorzás helyén a nevezőben minusz van.

Szóval az integrál: T = 100*integrál[0-tól 52.4-ig](dx /(55-0.02*x^2))

Így a kód:

#include <stdio.h>

int main() {

	int a=0, b=52,op=1000, i=0;
	float da, db, dx;
	float alsoosszeg = 0;
	float felsoosszeg = 0;

	dx = (float)(b-a)/op;

	for (i=0; i<op; i++) { //vegre mehet nullatol:)
	da = a + (i*dx);
	db = a + ((i+1)*dx);
	alsoosszeg+= dx*(1/(55-0.02*da*da)); // itt szamolja a fuggvenyerteket
	felsoosszeg+= dx*(1/(55-0.02*db*db)); // ez most az 1/(55-0.02*x^2) fuggveny
	}
	alsoosszeg=alsoosszeg*100;
	felsoosszeg=felsoosszeg*100;

	printf("Az also kozelito osszeg: %f\n",alsoosszeg);
	printf("A felso kozelito osszeg: %f\n",felsoosszeg);
}

Így most az eredmény : -146.03 , de ez még mindig nem tűnik megfelelőnek.

(%i36) 100*integrate(1/(55-0.02*x^2),x,0,52.4);
(%o36) -(50*sqrt(110)*log(1296.169811320682-123.5849056603705*sqrt(110)))/11
(%i37) float(%);
(%o37) 374.7258588151074

Na, erre mar kihozza a maxima a vart eredmenyt.

52.4, az a +0.4 sokat szamait.

Es az opot is told sokkal feljebb.

52-es határral az eredmény -146.03
53-assal : -120.6

Ha viszont a b típusát float-ra állítom és 52.4-es értéket adok neki, akkor 14.13 jön ki (ezek mind felsőhatár eredmények).
És ugyanekkor ha opot felnyomom 1000-ről 10000-re -28.8-at kapok.

Itt valami elvi hiba van a programban, csak azt nem tudom mi.

Lefuttattam a fenti kódot b típusát floatra állítva. és 52.4-el, 10000es oppal:

Az also kozelito osszeg: 371.711243
A felso kozelito osszeg: 377.881226

Ha ez segít valamit ...

Megerősítem, nekem is annyi. :-)

KisKresz

Hát ennek örülök, ugyanakkor nem igazán értem.
Nekem ugyanazokkal a változókkal amiket írtok -28-at ad.

Az számíthat, hogy én AIX alatt fordítom/futtatom?

szerk.: semmi, kipróbáltam linux alatt, ugyanúgy rossz.

Légysz írjtátok már be a pontos kódot, amit ti fordítotok, köszi

WinXP, dev-c++

#include <stdio.h>

int main() {

	int a=0,op=10000, i=0;
	float b=52.4;
	float da, db, dx;
	float alsoosszeg = 0;
	float felsoosszeg = 0;

	dx = (float)(b-a)/op;

	for (i=0; i<op; i++) { 
	da = a + (i*dx);
	db = a + ((i+1)*dx);
	alsoosszeg+= dx*(1/(55-0.02*da*da)); 
	felsoosszeg+= dx*(1/(55-0.02*db*db));
	}
	alsoosszeg=alsoosszeg*100;
	felsoosszeg=felsoosszeg*100;

	printf("Az also kozelito osszeg: %f\n",alsoosszeg);
	printf("A felso kozelito osszeg: %f\n",felsoosszeg);
}

--
"my mind had skipped town and left me behind to pay the rent"

És igen. Működik! :D

Köszönöm szépen mindenkinek a segítséget!