Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/34: Рейтинг темы: голосов - 34, средняя оценка - 4.88
Человекдождя
0 / 0 / 0
Регистрация: 09.04.2012
Сообщений: 2
1

Вычисление интеграла методом Монте-Карло

13.04.2012, 00:34. Просмотров 6158. Ответов 5
Метки нет (Все метки)

Здравствуйте. Необходима программа, вычисляющая интеграл методом Монте-Карло для функции z=(8*x*sin(x)+7*x*y^3*(cos(y)^2))/((cos(x-y))^(1/2)) в пределах: x=[0,1], y=[0,1], z=[0,10] (реальное значение интеграла)
Среднее значение интеграла за 10 опытов не должно отклоняться от реальной величины более, чем на 0,01.
Мой вариант программы стабильно ошибается на 0,1! Вместо должных ~2,96 получается ~2.86. Помогите пожалуйста найти проблему.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h> 
#include <time.h> 
#include<clocale>
 
 
void main()
{
    setlocale(LC_CTYPE, "");
    srand((unsigned)time(NULL));
    printf("Функция: z=(8*x*sin(x)+7*x*y^3*cos(y)^2))/cos(x-y)^(1/2)\n");
 
    float Zmax=0;
    for(float x=0;x<=1;x=x+0.01)
    {
        for(float y=0;y<=1;y=y+0.01)
        {
            if(Zmax<(float)(8*x*sin(x)+7*x*pow(y,3)*pow(cos(y),2))/pow(cos(x-y),1/2))
            {
                Zmax=(float) (8*x*sin(x)+7*x*pow(y,3)*pow(cos(y),2))/pow(cos(x-y),1/2);
            }
        }
    }
    
    float SumINTEGR=0;//Сумма интегралов за 10 опытов
    
    for(int i=1;i<=10;i++)
        {
            float X,Y,Z;// Рандомные точки 
            int HIT=0;// Число попаданий точек в искомый объем под поверхностью функции
            float INTEGR=0;//Значение интеграла
            
            for(float N=1;N<=183065;N++)
            {
                X=(float)(rand()%101)/100;
                Y=(float)(rand()%101)/100;
                Z=(float)(rand()%1001)/100;
    
                if(Z<=(8*X*sin(X)+7*X*pow(Y,3)*pow(cos(Y),2))/pow(cos(X-Y),1/2))
                    {
                        HIT=HIT+1;
                    }
            }
            
            INTEGR=(float)HIT/183065*10;
            SumINTEGR=SumINTEGR+INTEGR;
        }
    
    float averINTEGR=SumINTEGR/10;// Среднее значение интеграла в 10 случаях
    printf("Значение интеграла - %f\n", averINTEGR);
    
    printf("Z максимальное - %f",Zmax);
    getch();
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.04.2012, 00:34
Ответы с готовыми решениями:

Поиск интеграла методом Монте-Карло
Добрый день. Неполучается написать код для метода монте-карло для поиска...

Вычисление кратных интегралов методом монте-карло
Помогите. Неделю как перешел с Паскаля на С/С++ Не понимаю в чем ошибка. На...

Нахождение значения Пи методом Монте-Карло. Вычисление неправильное или в коде ошибся?
Всем привет! Задачка на нахождение значения ПИ по методу Монте Карло. В...

Монте Карло для двойного интеграла
Нужно найти двойной интеграл методом Монте Карло. Уже неделю лазил по нете,...

Решить интеграл методом Монте-Карло
Помогите добить задачу, беда в том что не могу сообразить как срандомировать...

5
alkagolik
Заблокирован
13.04.2012, 15:39 2
привел в компактный вид, исправил много "невниманий", типа вместо числа с плавающей точкой ставится целое, объявления переменных не по ANSI, в то время как void main{} подразумевает именно его и т.д. вынес формулу в одну функцию для удобстваточность немного отлоняется, но это неудивительно. Вот для размышлений.
Формат данных с плавающей точкой
http://www.cyberforum.ru/blogs/18334/blog88.html
Точности вычислений double
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
/*
float f( float x, float y ) {
    return (float) ( ( 8. * x * sinf( x ) + 7. * x * powf( y, 3. ) * powf( cosf( y ), 2. ) )\
                     / powf( cosf( x - y ), ( 1./2. ) ) );
}
 
int main() {
 
    srand((unsigned)time(NULL));
    printf("Функция: z=(8*x*sin(x)+7*x*y^3*cos(y)^2))/cos(x-y)^(1/2)\n");
 
    float Zmax = 0., t, x = 0., y, z;
    float SumINTEGR = 0., INTEGR = 0.;
    int i, j, HIT;
 
    for ( i = 0; i < 100; ++i ) {
 
        y = 0.;
 
        for ( j = 0; j < 100; ++j ) {
            if( Zmax < ( t = f( x, y ) ) )
                Zmax = t;
            y += 0.01f;
        }
        x +=0.01f;
    }
 
 
    for( i = 0; i < 10; ++i ) {
 
        // Число попаданий точек в искомый объем под поверхностью функции
        HIT = 0;
 
        //Значение интеграла
        INTEGR = 0.;
 
        for( j = 0; j < 183065; ++j ) {
 
            x = (float) ( rand() % 101 ) / 100;
            y = (float) ( rand() % 101 ) / 100;
            z = (float) ( rand() % 1001 ) / 100;
 
            if( z <= f( x, y ) )
                ++HIT;
 
        }
 
        INTEGR = (float) HIT / 183065.f * 10.f;
        SumINTEGR += INTEGR;
    }
 
    // Среднее значение интеграла в 10 случаях
    float averINTEGR = SumINTEGR / 10.f;
 
    printf( "Значение интеграла   = %f\n", averINTEGR );
    printf( "Z максимальное       = %f\n", Zmax );
 
    return 0;
}
*/
 
double f( double x, double y ) {
    return ( ( 8. * x * sin( x ) + 7. * x * pow( y, 3. ) * pow( cos( y ), 2. ) )\
                     / pow( cos( x - y ), ( 1./2. ) ) );
}
 
int main() {
 
    srand( time ( NULL ) );
    printf("Функция: z=(8*x*sin(x)+7*x*y^3*cos(y)^2))/cos(x-y)^(1/2)\n");
 
    double Zmax = 0., t, x = 0., y, z;
    double SumINTEGR = 0., INTEGR = 0., averINTEGR;
    int i, j, HIT;
 
    for ( i = 0; i < 100; ++i ) {
 
        y = 0.;
 
        for ( j = 0; j < 100; ++j ) {
            if( Zmax < ( t = f( x, y ) ) )
                Zmax = t;
            y += 0.01;
        }
        x +=0.01;
    }
 
 
    for( i = 0; i < 10; ++i ) {
 
        // Число попаданий точек в искомый объем под поверхностью функции
        HIT = 0;
 
        //Значение интеграла
        INTEGR = 0.;
 
        for( j = 0; j < 183065; ++j ) {
 
            x = (double) ( rand() % 101 ) / 100;
            y = (double) ( rand() % 101 ) / 100;
            z = (double) ( rand() % 1001 ) / 100;
 
            if( z <= f( x, y ) )
                ++HIT;
 
        }
 
        INTEGR = (double) HIT / 183065. * 10.;
        SumINTEGR += INTEGR;
    }
 
    // Среднее значение интеграла в 10 случаях
    averINTEGR = SumINTEGR / 10.;
 
    printf( "Значение интеграла   = %lf\n", averINTEGR );
    printf( "Z максимальное       = %lf\n", Zmax );
 
    return 0;
}
0
Человекдождя
0 / 0 / 0
Регистрация: 09.04.2012
Сообщений: 2
22.04.2012, 15:47 3
Спасибо, конечно, но величина не должна отклоняться от реальной более чем на 0.01. А тут выходит ~0.04
0
grizlik78
Эксперт С++
1987 / 1480 / 191
Регистрация: 29.05.2011
Сообщений: 3,059
22.04.2012, 18:37 4
Случайная величина слишком уж дискретная, всего 101 значение по x и по y.
Вот так должно стать получше:
C
1
2
3
x = (double) ( rand() ) / RAND_MAX;
y = (double) ( rand() ) / RAND_MAX;
z = (double) ( rand() ) * 10.0 / RAND_MAX;
Хотя мне трудно понять задание в таком виде. Почему значение функции ограничивается заданием? Или это не ограничение, а просто указан известный заранее диапазон значений?
0
alkagolik
Заблокирован
22.04.2012, 19:18 5
grizlik78, с твоими поправками
вывод
Значение интеграла = 2.972299
Значение интеграла = 2.967990
Значение интеграла = 2.966362
Значение интеграла = 2.972376
Значение интеграла = 2.967536
Значение интеграла = 2.967203
Значение интеграла = 2.967055
Значение интеграла = 2.959932
Значение интеграла = 2.963030
Значение интеграла = 2.972458
Значение интеграла = 2.966919
Значение интеграла = 2.969180
Значение интеграла = 2.967006
Значение интеграла = 2.963576
Значение интеграла = 2.963499
Значение интеграла = 2.969006
Значение интеграла = 2.967361
Значение интеграла = 2.967842
Значение интеграла = 2.970098
Значение интеграла = 2.973539
. По ссылке на вольфрам в посте 1 указано неверное значение, а именно не 2.9682 ~ 2.97 как там, а ~2.96 - что неверно. Человекдождя, опиши все константы, которые используешь.
0
Malishka
0 / 0 / 0
Регистрация: 18.03.2016
Сообщений: 3
15.12.2012, 19:33 6
у кого-нибудь есть готовая программка для вычисления двойного интеграла методом монте-карло? та, что выше не понятна( пожалуйста, помогите...
0
15.12.2012, 19:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.12.2012, 19:33

Найти число Pi методом Монте-Карло. Ошибка в выводе числа
Задача состоит в том, чтоб найти число Пи методом Монте-Карло плюс куча мелких...

Вычислить, используя метод Монте-Карло, определенный интеграл
Добрый день! Исчислить, используя метод Монте-Карло, определенный интегралом:...

Разработать программу для вычисления интеграла методом трапеций и методом Симпсона
Разработать программу для вычисления интеграла методом трапеций и методом...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru