Форум программистов, компьютерный форум, киберфорум
Наши страницы

C для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 46, средняя оценка - 4.61
Человекдождя
#1

Вычисление интеграла методом Монте-Карло - C (СИ)

13.04.2012, 00:34. Просмотров 5875. Ответов 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();
 
}
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.04.2012, 00:34
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вычисление интеграла методом Монте-Карло (C (СИ)):

Поиск интеграла методом Монте-Карло - C (СИ)
Добрый день. Неполучается написать код для метода монте-карло для поиска интеграла. Помогите пожалуйста. fun = sin(x) { ...

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

Нахождение значения Пи методом Монте-Карло. Вычисление неправильное или в коде ошибся? - C (СИ)
Всем привет! Задачка на нахождение значения ПИ по методу Монте Карло. В методичке сказано: &quot;You should use this expression for...

Монте Карло для двойного интеграла - C (СИ)
Нужно найти двойной интеграл методом Монте Карло. Уже неделю лазил по нете, нашел пару программ на Pascal но у всех нашел ошибки и так и не...

Решить интеграл методом Монте-Карло - C (СИ)
Помогите добить задачу, беда в том что не могу сообразить как срандомировать точки в пределах для решения такого интеграла: pow(sin(x),...

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

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
Человекдождя
22.04.2012, 15:47 #3
Спасибо, конечно, но величина не должна отклоняться от реальной более чем на 0.01. А тут выходит ~0.04
grizlik78
Эксперт С++
1967 / 1460 / 120
Регистрация: 29.05.2011
Сообщений: 3,022
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
15.12.2012, 19:33 #6
у кого-нибудь есть готовая программка для вычисления двойного интеграла методом монте-карло? та, что выше не понятна( пожалуйста, помогите...
15.12.2012, 19:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.12.2012, 19:33
Привет! Вот еще темы с ответами:

Вычислить, используя метод Монте-Карло, определенный интеграл - C (СИ)
Добрый день! Исчислить, используя метод Монте-Карло, определенный интегралом: y=sin(2x) + cos(x) x ∈ Правильно ли это? ...

Разработать программу для вычисления интеграла методом трапеций и методом Симпсона - C (СИ)
Разработать программу для вычисления интеграла методом трапеций и методом Симпсона, оформив каждый способ в виде отдельной функции. Вывести...

Вычисление интеграла - C (СИ)
Доброго времени суток! Имеется след задача. ВЫчислить значение интеграла с заданой точность eps = 10^-3. Для средних прямоугольников. Кто...

Задача на вычисление определенного интеграла - C (СИ)
Помогите исправить ошибку. В методе Симпсона кол-во итераций почему-то больше, чем в других, хотя он наиболее точен. #pragma...


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

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

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