Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Całkowanie Monte Carlo

Ostatnio zmodyfikowano 2013-06-08 18:24
Autor Wiadomość
booyaka
Temat założony przez niniejszego użytkownika
Całkowanie Monte Carlo
» 2013-06-08 13:11:00
Witam,

Mam za zadanie napisać program do całkowania metodą Monte Carlo, dla dowolnego wprowadzonego z klawiatury wielomianu i przedziału całkowania. Napisałem coś takiego:

C/C++
#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

long double ZwrocWartoscFunkcji( int * wspolczynniki, int n, long double x );

int main()
{
    int ilosc, an, i, b, c, n;
    // Wczytujemy dane dotyczące całkowania, funkcje, przedziały.
   
    cout << "Podaj wspolczynnik przy n-tej potedze: " << endl;
    cin >> an;
   
    int * wspolczynniki = new int[ an ];
   
    for( i = 0; i <= an; i++ )
    {
        if( i == 0 ) cout << "Podaj wartosc wyrazu wolnego: " << endl; else
        cout << "Podaj wspolczynnik " << i << "stopnia wielomianu" << endl;
        cin >> wspolczynniki[ i ];
    }
   
    cout << "Podaj poczatek przedzialu calkowania: " << endl;
    cin >> b;
   
    cout << "Podaj koniec przedzialu calkowania: " << endl;
    cin >> c;
   
    // Wypisanie pobranej funkcji
    cout << "Wprowadzony wielomian to: " << endl;
    for( i = an; i >= 0; i-- )
    {
        if( i == 0 ) cout << wspolczynniki[ i ]; else
        cout << wspolczynniki[ i ] << "x^" << i;
        if( i > 0 )
        if( wspolczynniki[ i ] >= 0 ) cout << "+"; else cout << "-";
    }
   
    cout << endl << "Podaj dokladnosc wyznaczania max/min funkcji: ";
    cin >> n;
   
    // Max i Min lokalne funkcji w podanych przedziałach wartości
    long double wartosc = 0, maximum = 0, minimum = 0, krok = 1 / n;
   
    // Wyliczamy wartosci funkcji w okreslonym przedziale, okreslamy minimum i maximum funkcji.
    for( double i = b; i <= c; i = i + krok )
    {
        wartosc = ZwrocWartoscFunkcji( wspolczynniki, an, i );
       
        if( wartosc > maximum ) maximum = wartosc;
       
        if( wartosc < minimum ) minimum = wartosc;
       
    }
   
    // Wyznaczamy wysokosc i szerokosc zakresu w ktorym bedziemy losowac.
    long double wysokosc, szerokosc;
   
    // Szerokosc to roznica przedzialu koncowego i poczatkowego.
    szerokosc =( long double )( c - b );
   
    // Wysokosc to roznica wartosci maxymalnej i minimalnej funkcji w przedziale.
    wysokosc = maximum - minimum;
   
    // Losowanie w punktow
    cout << "Podaj liczbe losowań: " << endl << "Uwaga! Zakres od 1 do 2^32 - 1" << endl;
    cin >> ilosc;
   
    long double X, Y;
    int licznik;
   
    for( i = 0; i < ilosc; ilosc++ )
    {
        X =(( long double ) rand() /( RAND_MAX ) ) *( c - b ) + b;
        Y =(( long double ) rand() /( RAND_MAX ) ) *( wysokosc - szerokosc ) + szerokosc;
       
        wartosc = ZwrocWartoscFunkcji( wspolczynniki, an, i );
       
        if( Y > 0 && wartosc > 0 && Y <= wartosc ) licznik++;
       
        if( Y < 0 && wartosc < 0 && Y >= wartosc ) licznik--;
       
    }
   
    // Wartosc calki
    long double P;
   
    P =( szerokosc * wysokosc ) *( long double ) licznik /( long double ) ilosc;
   
    cout << "Punkty trafione: " << licznik << endl;
    cout << "Wartość calki: " << P << endl;
   
    getchar();
    getchar();
    return 0;
}

// Obliczanie wartości funkcji w x
long double ZwrocWartoscFunkcji( int * wspolczynniki, int n, long double x ) {
    long double funkcja = 0;
   
    for( int i = 0; i < n; i++ )
         funkcja +=(( long double ) wspolczynniki[ i ] ) *(( long double ) pow( x,( double )( n - i - 1 ) ) );
   
    return funkcja;
}

Program niestety się zawiesza. Coś jest nie tak jak trzeba w momencie wyznaczania max / min funkcji w przedziale. Nie jest w stanie się doliczyć nawet dla małej dokładności. Dlaczego tak jest?

Z góry dzięki za pomoc,
P-85145
pekfos
» 2013-06-08 17:55:10
Zmień
C/C++
long double wartosc = 0, maximum = 0, minimum = 0, krok = 1 / n;
na
C/C++
long double wartosc = 0, maximum = 0, minimum = 0, krok = 1.0 / n;
P-85180
booyaka
Temat założony przez niniejszego użytkownika
» 2013-06-08 18:11:06
Poprawiłem. Program zawiesza się jednak teraz po wprowadzeniu ilości losowań punktów.

Poprawiłem kod na:

C/C++
long double X = 0.0, Y = 0.0;
int licznik = 0;

Nie pomogło.
P-85184
pekfos
» 2013-06-08 18:20:06
C/C++
for( i = 0; i < ilosc; ilosc++ )
Nie powinno być i++?
P-85185
booyaka
Temat założony przez niniejszego użytkownika
» 2013-06-08 18:24:39
Moje bardzo duże niedopatrzenie, dzięki za pomoc. Program już działa tak jak powinien.
P-85187
« 1 »
  Strona 1 z 1