Форум программистов, компьютерный форум CyberForum.ru

Вычисление интеграла - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 33, средняя оценка - 4.79
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
08.10.2009, 21:35     Вычисление интеграла #1
Считаю интеграл на промедутке от -1 до 3... Интеграл a*a*a*a. Точность вычисления 0.00001... Код выполняется 10-12 секунд. Это нормально или можно оптимизировать? Метод вычисления прямоугольники или трапеции ( в принципе без разницы.. И там и там где-то 10 сек. ) На других функциях ( y = sin x, y = x) менее чем за 150 миллисекунд. Что можете сказать? Приложу код на С++, но это не важно, важен алгоритм...
Код

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
double IntRect(fptr f, double xn, double xk, double eps,long int* n, bool * br)
{
    
    if ( xk <= xn) 
    {
        cout << "Err";
        return 0;
    }
    double S1 = 0, S2;
    double delta = DELTA_PRESET;
 
    (*n) = 0; // Обнуляем число шагов
    DELTA_DEC  = 0.5; //Коэффициент уменьшения  
    do
    {
        S2 = S1;
        S1 = 0;
        
        (*n)++;
        
        //double delta = ( xk - xn ) / eps;
        for (double i = xn; i < xk + delta; i += delta)
        {
            if ( i > xk)
            {
                S1 = S1 * delta; // Умножаем сумму высот на дельта
                S1 = S1 + ( delta - (i - xk) ) * ( f( (i - delta + xk) /2.0)   ); // Находим интеграл последнего отрезка
                break;
            }
            S1 = S1 + f(i + delta / 2.0);
            
        }
        if ( (clock() - t1) > MAX_TIME)
        {
                (*br) = true; // Выполнение прервалось
                break;
        }
        delta *= DELTA_DEC; // Уменьшаем  дельту в DELTA_DEC раза
        
 
    } while ( fabs(S1-S2) > eps);
    return ( (S1+S2) / 2);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.10.2009, 21:35     Вычисление интеграла
Посмотрите здесь:

C++ Вычисление интеграла
C++ вычисление интеграла
Вычисление интеграла C++
C++ Вычисление интеграла
Вычисление определенного интеграла си++ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
08.10.2009, 22:28     Вычисление интеграла #2
Код не полный - невозможно выполнить.
И вообще неясно при каких именно значениях ты его запускаешь.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
09.10.2009, 12:30  [ТС]     Вычисление интеграла #3
C++
1
data[i].method1 = IntRect(f_array[i], -1, 3, eps, &(data[i].n1), &(data[i].break_1));
- Запуск кода...
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
// Структура, где сохранены значения
struct dataS
{
    double method1; // Значение метода 1
    double method2; // Значение метода 2
    double value;  // Истинное значение ( которое должны получить)
    long int n1; // Число отрезков, при которых достигнута точность для первого метода
    long int n2; // Число отрезков, при которых достигнута точность для второго метода
    double eps; // Точность вычисления
    long process_time_1;
    long process_time_2;
    bool break_1;
    bool break_2;
};
 
// Функции, интегралы которых надо вычислить
double f1(double x)
{
    return (x);
};
double f2(double x)
{
    return (sin( 22 * x ));
};
double f3(double x)
{
    return ( x*x*x*x );
};
double f4(double x)
{
    return (atan(x));
};
- Массив функций
C++
1
2
3
4
5
6
7
// Массив наших функций
typedef double (* fptr) (double );
 
 
 
fptr f_array[] = {f1 , f2 , f3 , f4}; // Массив указателей на функции
 функций
Я извиняюсь, что пишу не в том разделе.. Но вопрос именно по алгоритму((
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
09.10.2009, 18:00     Вычисление интеграла #4
Ты выложи код всей программы !
И пиши лучше в разделе C/C++
Phantom
Эксперт C++
 Аватар для Phantom
3159 / 841 / 15
Регистрация: 29.12.2008
Сообщений: 952
09.10.2009, 21:42     Вычисление интеграла #5
GRANDEATH, перенести тему в C++ ?
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 12:09  [ТС]     Вычисление интеграла #6
Я выложил код функции... Она выполняется 10-15 секунд... Что в ней кривого??? Функция выполняется со следующими параметрами...f_array[i], при i = 2 - указатель на функцию f3 -
C++
1
2
3
4
double f3(double x)
{
        return ( x*x*x*x );
};
double xn, double xk - начальное и конечное значение отрезка... В данном случае -1 и 3. eps - Точность вычисления, равная 0.00001...
&(data[i].n1), &(data[i].break_1 - переменные, которые функция возвращает. то есть они не влияют на результат...

Вопрос банально в чем - можно ли сосчитать определенный интеграл x*x*x*x на промежутке -1 ,3 с точностью 0.00001 МЕНЕЕ чем за 7 сек. ( Проц- AMD Одноядерник где-то 1.7 Гига герца) Если нет - значит свалим на различие архитектуры и т.д. и вопрос снят Если же можно, тогда проблема с алгоритмом...
Число логически - интервал надо разделить на отрезки, длина которых не больше 0.000 001.. Хотя бы для того, что бы, к примеру для отрезка, начинающегося с 2 - f(2 + 0.000 001) < eps... У нас тама 4-я степень.. Мало того что перемножения double на double немало времени требует, так ещё и считать это 4 миллиона раз.... Не подскажете, где я туплю?
P.S. Препод говорит что у него считается менее чем 2 секнды...
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 12:12     Вычисление интеграла #7
Пока нет кода всей программы говорить как бы не о чем.
можно ли сосчитать определенный интеграл
Ты сам ответил - можно. Препод считает менее чем за 2 сек
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 12:38  [ТС]     Вычисление интеграла #8
Вот я решил проверить.. Вруг мы не поняли друг друга)) Вот код проги.. Извиняюсь за кривые комменты...
Код

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
// Lab_7.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include "funct.h"
#include <Windows.h>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
 
    setlocale(0,"russian");
    cout << "Введите точность вычислений" << endl;
    
    double eps = 0;
    cin >> eps;
    
    
    dataS *data = new dataS[4]; // Массив значений
    
    // Вычисляем значения интегралов
    for (int i = 0; i < 4; i++)
    {
        
        
        data[i].break_1 = false; //// Выполнение не прекращено
        data[i].n1 = 0;
        Sleep(1);
        t1 = clock();
        data[i].method1 = IntRect(f_array[i], -1, 3, eps, &(data[i].n1), &(data[i].break_1));
        t2 = clock();
        data[i].process_time_1 = t2 - t1;
 
        
        data[i].break_2 = false; // Выполнение не прекращено
        data[i].n2 = 0;
        Sleep(1);
        t1 = clock();
        data[i].method2 = IntSum(f_array[i], -1, 3, eps, &(data[i].n2), &(data[i].break_2));
        t2 = clock();
        data[i].process_time_2 = t2 - t1;
 
        data[i].eps = eps; 
        data[i].value = f_array_res[i](-1,3);
    }
 
 
    //cout << IntRect(f_array[0], 01, 0,1, NULL);
 
    for (int i = 0; i < 4; i++)
    {
        cout << endl << endl << endl;
        cout << "Funct#" << i << endl;
        print(&(data[i]));
        
    }
 
 
    // Очистка памяти
    delete data;
    return 0;
}


funct.h - описание функций, переменных и т.д.
Еще файл с кодом

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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#include <math.h>
#include <iostream>
#include <iomanip>
#include <time.h>
 
 
#define DELTA_PRESET 0.0001 // Начальный отрезок
#define TIME_BORDER 300 // Время в миллисекундах для вывода предупреждения...
#define MAX_TIME 10000 //Максимальное время выполения
double  DELTA_DEC  = 0.3; //Коэффициэнт уменьшения
 
clock_t t1, t2; // Переменные для храниения времени
 
using namespace std;
 
// Структура, где сохранены значения
struct dataS
{
    double method1; // Значение метода 1
    double method2; // Значение метода 2
    double value;  // Истинное значение ( которое должны получить)
    long int n1; // Число отрезков, при которых достигнута точность для первого метода
    long int n2; // Число отрезков, при которых достигнута точность для второго метода
    double eps; // Точность вычисления
    long process_time_1;
    long process_time_2;
    bool break_1;
    bool break_2;
};
 
// Функции, интегралы которых надо вычислить
double f1(double x)
{
    return (x);
};
double f2(double x)
{
    return (sin( 22 * x ));
};
double f3(double x)
{
    return ( x*x*x*x );
};
double f4(double x)
{
    return (atan(x));
};
 
 
// Функции, которые выозвращают точное значение интеграла
double f1_res(double a, double b)
{
    return ( (b*b-a*a)/2.0 );
};
double f2_res(double a, double b)
{
    return (  (cos(a*22.0)-cos(b*22.0) )/22.0 );
};
double f3_res(double a, double b)
{
    return (  (b*b*b*b*b-a*a*a*a*a)/5.0 );
};
double f4_res(double a, double b)
{
    return ( b*atan(b)-a*atan(a)-(log(b*b+1)-log(a*a+1))/2.0 );
};
 
 
 
// Массив наших функций
typedef double (* fptr) (double );
typedef double (* fptr_res) (double, double );
 
 
fptr f_array[] = {f1 , f2 , f3 , f4}; // Массив указателей на функции
fptr_res f_array_res[] = {f1_res , f2_res , f3_res , f4_res}; // Массив указателей на точное значение функций
 
 
 
 
 
 
 
/*
f - имя интегрируемой функции,
xn, xk – границы интервала интегрирования,
eps – требуемая точность,
n – число отрезков, при котором достигнута требуемая точность (выходной). 
*/
 
double IntRect(fptr f, double xn, double xk, double eps,long int* n, bool * br)
{
    
    if ( xk <= xn) 
    {
        cout << "Err";
        return 0;
    }
    double S1 = 0, S2;
    double delta = DELTA_PRESET;
 
    (*n) = 0; // Обнуляем число шагов
    DELTA_DEC  = 0.5; //Коэффициент уменьшения  
    do
    {
        S2 = S1;
        S1 = 0;
        
        (*n)++;
        
        //double delta = ( xk - xn ) / eps;
        for (double i = xn; i < xk + delta; i += delta)
        {
            if ( i > xk)
            {
                S1 = S1 * delta; // Умножаем сумму высот на дельта
                S1 = S1 + ( delta - (i - xk) ) * ( f( (i - delta + xk) /2.0)   ); // Находим интеграл последнего отрезка
                break;
            }
            S1 = S1 + f(i + delta / 2.0);
            
        }
        if ( (clock() - t1) > MAX_TIME)
        {
                (*br) = true; // Выполнение прервалось
                break;
        }
        delta *= DELTA_DEC; // Уменьшаем  дельту в DELTA_DEC раза
        
 
    } while ( fabs(S1-S2) > eps);
    return ( (S1+S2) / 2);
}
 
 
int print(dataS* data)
{
    cout << endl;
    cout << setw(20) << left <<"Значение 1:" << setw(12) << right << fixed << data->method1 << endl;
    cout << setw(20) << left <<"Число шагов 1:" << setw(12) << right << data->n1 << endl;
    cout << setw(20) << left <<"Время выполения 1-го" << setw(12) << right << data->process_time_1;
    if (data->process_time_1 > TIME_BORDER) cout << "  !!!";
    if (data->break_1)  cout << "  break";
    cout<< endl;
 
    cout << setw(20) << left <<"Значение 2:" << setw(12) << right << fixed << data->method2 << endl;
    cout << setw(20) << left <<"Число шагов 2:" << setw(12) << right << data->n2 << endl;
    cout << setw(20) << left <<"Время выполения 2-го" << setw(12) << right  << data->process_time_2;
    if (data->process_time_2 > TIME_BORDER) cout << "  !!!";
    if (data->break_2)  cout << "  break";
    cout<< endl;
 
    cout << setw(20) << left <<"Точность" << setw(12) << right << data->eps << endl;
    cout << setw(20) << left <<"Точное значение" << setw(12) << right  << fixed <<data->value << endl;
 
    
    return 0;
}
 
double IntSum(fptr f, double xn, double xk, double eps,long int* n, bool *br)
{
 
    DELTA_DEC  = 0.5; //Коэффициэнт уменьшения  
    if ( xk <= xn) 
    {
        cout << "Err";
        return 0;
    }
 
    double S1 = 0, S2;
    double f1,f2;
    double delta = DELTA_PRESET;
    (*n) = 0; // Обнуляем число шагов
    do
    {
        (*n)++;
        S2 = S1;
        S1 = 0;
        
        //double delta = ( xk - xn ) / eps;
        for (double i = xn; i < xk + delta; i += delta)
        {
            if ( i > xk)
            {
                S1 = S1 * delta; // Умножаем сумму высот на дельта
                S1 = S1 + ( delta - (i - xk) ) * ( f(i-delta) + f(xk)) / 2.0; // Нахожим интеграл последнего отрезка
                break;
            }
            f1 = f(i);
            f2 = f(i + delta);
            S1 = S1 +  ( ( f1 + f2) / 2.0 );
            
 
        }
        if ( (clock() - t1) > MAX_TIME)
        {
                if ( fabs(S1-S2) < eps) break; // Все нормально
 
                (*br) = true; // Выполнение прервалось
                break;
        }
        delta *= DELTA_DEC; // Уменьшаем  дельту в DELTA_DEC раза
        //DELTA_DEC  = atan(2.0 * (*n)) * 2 / 3.1415926 - 0.1; //Изменяем коэффициэнт уменьшения
        
        if (DELTA_DEC >= 1)
        {
            cout << "Error... DELTA_DEC < 1.0" << endl;
            break;
        }
 
 
    } while ( fabs(S1-S2) > eps);
 
    return ( (S1+S2) / 2);
 
 
};
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 12:42     Вычисление интеграла #9
delta *= DELTA_DEC
Вот это зачем ?
Я думаю из-за этого долго считает

Добавлено через 1 минуту
1) Не нужно clock() каждый раз проверять.
Достаточно ограничить число циклов.
2)
double IntRect(fptr f, double xn, double xk, double eps,long int* n, bool * br)

По указателю медленно - лучше скопировать к себе в локальную переменную.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 12:47  [ТС]     Вычисление интеграла #10
1. Как же без дельта... дельта - длина отрезка.... Мы ее и уменьшаем..Что бы получить заданную точность... Сначала дельта - 0.0001 а потом мы ее уменьшаем...
2. Насчет clock() - согласен... Но он считает ее раз 50-20 на производит. не сказывается... ( 99 процентов жрет for) Тем более как ограичить по времени выполнение?
3. немного не понял... Что имел ввиду?
C++
1
2
3
4
5
    if (DELTA_DEC >= 1)
                {
                        cout << "Error... DELTA_DEC < 1.0" << endl;
                        break;
                }
вот это ещё не успел убрать.. Это точно не надо))
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 12:51     Вычисление интеграла #11
Расскажи про алгоритм.
Ты считаешь интеграл как сумму S1, S2.
А условием окончания счета служит что ?
fabs(S1-S2)<eps.
То есть когда разница соседних сумм станет меньше чем eps ?

Добавлено через 1 минуту
Просто ты уменьшает отрезок в 2 раза.
Это конечно хорошо, но сразу в 2 раза увеличивается время счета одной суммы.

Добавлено через 45 секунд
Насчет 3.
double IntRect(fptr f, double xn, double xk, double eps,long int *pn, bool * br)

long n;

n= *pn;

// далее работаем с n

// в конце
*pn= n;
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 12:58  [ТС]     Вычисление интеграла #12
Задание такое - посчитать интеграл двумя способами
1. Прямоугольниками
2. Трапециями
В общем случае алгоритм такой - берем отрезок и делим его на частеи, длиной дельта... Считаем интеграл.. Потом уменьшаем дельта в 2 раза и снова считаем интеграл... Выполняем до тех пор, пока разница между 1-й и 2-й суммой не будет меньше eps... Тогда выводим среднее арифметическое между 1-й и 2-й суммой...

Я вообще не спец по си. Но какая разница, какая переменная? И так и так к ней идет обращение по адресу.. Какое дело процу, в какой адрес лепить значение?
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 13:00     Вычисление интеграла #13
Разница есть.
По-первых если переменная, тогда может быть выделен регистр.

Если переменная, то в коде сразу идет обращение по фиксированному адресу.
А если у тебя указатель на переменную, то идет обращение косвенное - это больше кода и дольше.

Хотя скорее всего дело не в этом

Добавлено через 31 секунду
Сейчас посчитаю интеграл не глядя на твой код - посмотрим что получится.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 13:02  [ТС]     Вычисление интеграла #14
Цитата Сообщение от odip Посмотреть сообщение
По-первых если переменная, тогда может быть выделен регистр.
Я как то об этом не подумал...(( Хм... Не знал.. Учту на заметку...

Остальные интегралы он считает с пол пинка))
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 14:04     Вычисление интеграла #15
Кажется я понял в чем прикол.
Программа

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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* Thread 55251 */
 
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
 
/********************************************************************/
typedef double (*func_t)(double);
 
 
/********************************************************************/
#define MAX_COUNT       100
#define FIRST_DELTA     0.0001
 
 
/********************************************************************/
int calc_integral( func_t f, double a, double b, double epsilon,
    double *psum, int *pcount
);
 
double f1( double x );
double integral_f1( double a, double b );
 
double f3( double x );
double integral_f3( double a, double b );
 
 
/********************************************************************/
int main( void ) {
 
int errcode, count, sec1;
clock_t c0, c1;
double a= -1.0, b= 3.0, epsilon= 0.00001;
double sum1, sum2, diff_sum;
 
 
/* Calc */
c0= clock();
errcode= calc_integral( f3, a, b, epsilon, &sum1, &count );
c1= clock()-c0;
sec1= c1/CLOCKS_PER_SEC;
sum2= integral_f3( a, b );
 
diff_sum= fabs(sum1-sum2);
 
/* Print */
printf( "a=%.10f b=%.10f epsilon=%.10f\n", a, b, epsilon );
printf( "sum1=%.10f count=%d sec1=%d errcode=%d\n", sum1, count, sec1, errcode );
printf( "sum2=%.10f\n", sum2 );
printf( "diff_sum=%.10f\n", diff_sum );
 
return 0;
 
} /* main() */
 
 
/********************************************************************/
int calc_integral( func_t f, double a, double b, double epsilon,
    double *psum, int *pcount ) {
 
long i, width;
int count, retcode= 0;
double x, delta, sum0, sum, diff_sum;
 
 
/* Check arguments */
if ( a>=b ) {
    fprintf( stderr, "Invalid arguments\n" );
    exit( 1 );
}
 
/* Calc width, delta */
delta= FIRST_DELTA;
 
/* Loop */
count= 0;
sum0= 0.0;
for ( ; ; ) {
 
    /* Calc width, delta */
    width= (b-a)/delta;
 
    /* Calc sum */
    sum= 0.0;
    for ( i= 0; i<width; i++ ) {
        x= a+i*delta;
        sum+= f( x );
    }
    sum*= delta;
 
    /* Check exit */
    count++;
    diff_sum= fabs( sum0-sum );
    
    printf( "count=%-3d width=%-10ld delta=%.10f sum=%.10f diff_sum=%.10f\n",
        count, width, delta, sum, diff_sum
    );
 
    if ( count>=MAX_COUNT ) { retcode= 1; break; }
    if ( diff_sum<epsilon ) { break; }
 
    /* Next */
    sum0= sum;
    delta*= 0.5;
 
}
 
/* Store */
*psum= sum;
*pcount= count;
 
/* Return */
return retcode;
 
} /* calc_integral() */
 
 
/********************************************************************/
double f1( double x ) {
 
return x;
 
} /* f1() */
 
double integral_f1( double a, double b ) {
 
return (b*b-a*a)/2.0;
 
} /* integral_f1() */
 
 
/********************************************************************/
double f3( double x ) {
 
return x*x*x*x;
 
} /* f3() */
 
 
/********************************************************************/
double integral_f3( double a, double b ) {
 
return (pow(b,5)-pow(a,5))/5.0;
 
} /* integral_f3() */


Вывод программы

Код
> integral.exe
count=1   width=39999      delta=0.0001000000 sum=48.7879011733 diff_sum=48.7879011733
count=2   width=79999      delta=0.0000500000 sum=48.7939502933 diff_sum=0.0060491200
count=3   width=159999     delta=0.0000250000 sum=48.7969750733 diff_sum=0.0030247800
count=4   width=319999     delta=0.0000125000 sum=48.7984875183 diff_sum=0.0015124450
count=5   width=639999     delta=0.0000062500 sum=48.7992437546 diff_sum=0.0007562363
count=6   width=1279999    delta=0.0000031250 sum=48.7996218761 diff_sum=0.0003781216
count=7   width=2559999    delta=0.0000015625 sum=48.7998109378 diff_sum=0.0001890616
count=8   width=5119999    delta=0.0000007813 sum=48.7999054688 diff_sum=0.0000945310
count=9   width=10239999   delta=0.0000003906 sum=48.7999527344 diff_sum=0.0000472656
count=10  width=20479999   delta=0.0000001953 sum=48.7999763672 diff_sum=0.0000236328
count=11  width=40959999   delta=0.0000000977 sum=48.7999881836 diff_sum=0.0000118164
count=12  width=81919999   delta=0.0000000488 sum=48.7999940918 diff_sum=0.0000059082
a=-1.0000000000 b=3.0000000000 epsilon=0.0000100000
sum1=48.7999940918 count=12 sec1=2 errcode=0
sum2=48.8000000000
diff_sum=0.0000059082


Добавлено через 6 минут
Прикол в начальном значении delta !
В зависимости как выбирать delta можно считать 0 секунд, 2 секунды или 30 секунд.
А все из-за выбранного алгоритма.
Просто если сумма изменяется сильно, то сходимость получается плохая и нужно считать дальше и дальше. Но удвоение delta ведет к удвоению времени счета !!!

Добавлено через 50 секунд
Вот и получается что при одном варианте все УЖЕ посчитано за 0 сек, а при кривом варианте сходится только при 30 сек.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 14:19  [ТС]     Вычисление интеграла #16
Спасибо за код, но она все равно считает не 2 секудны..У меня тоже 11 шагов.... Начальное дельта... Ты думаешь его стоит сделать поменьше?
Уменьшил до 0.000001... Хуже стало.. Увеличил - никак.. Практически все тоже..
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 14:24     Вычисление интеграла #17
sum1=48.7999940918 count=12 sec1=2 errcode=0
У меня на компе считает 2: sec1=2

Начальное не влияет.
Все время счета уходит на маленькие delta !
Честно говоря не знаю что делать. Пробовал делать delta*= 0.6;
delta*= 0.7;
Тогда вообще за 0 сек считает.
Но подбирать delta для каждой задачи это как-то странно

Суть в том, что мы имеем плохую сходимость.
И кривой метод.

Думаю можно ничего не делать - если объяснишь почему медленно считает

Кстати возможно что метод трапеций будет лучше.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 14:34  [ТС]     Вычисление интеграла #18
Я вот тоже думал что в сходимости проблема... Такое предчувствие, что надо было задавать уменьшение в зависимости от разницы между fabs(S1 - S2) и eps... Не да ладно... У меня код выполняется 4 секунды... Трапеции вроде тоже не лучше... Ай нет... Хуже... По моему начальному коду - первый метод - 3.8 сек... Трапеции (2-й метод) 7.5 секунд.. Ума не приложу, где подвох...
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
10.10.2009, 14:59     Вычисление интеграла #19
http://ru.wikipedia.org/wiki/Численное_интегрирование
Тут написано что все плохо. И есть другие методы - лучшей точности при том же кол-ве вычислений f(x) !
Но если тебе нужно считать именно заданными методами (прямоугольников и трапеций) - то ничего сделать нельзя.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.10.2009, 15:03     Вычисление интеграла
Еще ссылки по теме:

C++ Вычисление интеграла
Вычисление определенного интеграла C++
C++ C++ вычисление интеграла и табуляция

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

Или воспользуйтесь поиском по форуму:
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
10.10.2009, 15:03  [ТС]     Вычисление интеграла #20
Ну вообщем понятно)) Спс за разьяснения. По крайней мере будет уверенность в том что написал нормально)))
Yandex
Объявления
10.10.2009, 15:03     Вычисление интеграла
Ответ Создать тему
Опции темы

Текущее время: 18:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru