|
|
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток всем! Подскажите, можно ли как-нибудь быстро вычислить интеграл в VB6 с большой точностью от функции, заданной кусочно? Поясняю суть проблемы: в программе надо брать интеграл от кусочно заданной функции, он каждый раз в разных пределах от InFn до InFv. Вычисление "интеграла по определению" (рабиеним на трапеции шириной в 1 кГц) получается, но программа секунд на 20 подвисает пока его вычисляет. Интеграл берется по частоте (в кГц) от спектральной функции. Вся функция находится в пределах от 3 до 1800000 кГц. Пример одного из интегралов (из 5, которые в программе должно вычисляться): Здесь через Select Case задана кусочная функция Eshk = (10 ^ x) ^ 2 Function EshnS(ByVal InFn, ByVal InFv) As Double EshnS = 0 fx = InFn While fx < InFv Select Case fx Case 3 To 20 x = 3.52 - 2.18 * Log(fx) Case 20 To 5.8 * 10 ^ 3 x = 4 * (1.18 / ((0.78 * Log(fx)) ^ (2 / 3)) - 1) Case 5.8 * 10 ^ 3 To 5 * 10 ^ 4 x = 4 * (1.18 / ((0.78 * Log(fx)) ^ (2 / 3)) - 1) Case 5 * 10 ^ 4 To 3 * 10 ^ 5 x = 0.636 * Log(fx) - 5 Case 3 * 10 ^ 5 To 1.8 * 10 ^ 6 x = Log(0.03) End Select Eshk = (10 ^ x) ^ 2 fx = fx + 1 Select Case fx Case 3 To 20 x = 3.52 - 2.18 * Log(fx) Case 20 To 5.8 * 10 ^ 3 x = 4 * (1.18 / ((0.78 * Log(fx)) ^ (2 / 3)) - 1) Case 5.8 * 10 ^ 3 To 5 * 10 ^ 4 x = 4 * (1.18 / ((0.78 * Log(fx)) ^ (2 / 3)) - 1) Case 5 * 10 ^ 4 To 3 * 10 ^ 5 x = 0.636 * Log(fx) - 5 Case 3 * 10 ^ 5 To 1.8 * 10 ^ 6 x = Log(0.03) End Select Eshk1 = (10 ^ x) ^ 2 EshnS = EshnS + 1*(Eshk + Eshk1) / 2 ' берется значание функции на середине и умножается на 1 кГц (получаем площадь маленькой трапеции и далее суммируем) Wend End Function ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 17:58 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
InFn, InFv, fx = Variant объяви явно переменные! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 18:00 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
Konst_One, fx и так явно определена, а InFn, InFv - это входные переменные интеграл в процессе основного расчета вычисляется несколько раз и InFn, InFv все время разные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 18:19 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
авторKonst_One, fx и так явно определенаВ каком месте? Там вообще ни одна переменная не объявлена и входящие не типизированы, всё variant. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 18:45 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
Antonariy, я же привел часть программы (только функцию). Чуть выше в теле программы есть запись Public fx, x As Single (это же и есть объявление, или я уже что-то не понимаю?!). Но все же попробывал сделать как посоветовал Konst_One, определил входящие As Single, прирост в скорости не сильно заметен (может быть на пару секунд максимум ускорение и произошло, секундомером не засекал). Но все равно вычисление всех пяти интегралов идет около 1 минуты! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 19:01 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
sadem, у вас неведомое число раз вычисляются параметры, которые по сути своей должны быть константами в расчете. Типа 5.8 * 10 ^ 3 или 2/3 или, что совсем хорошо Log(0.03). Заведите для всех элементов такого рода переменные, вычислите их один раз в начале, а потом просто подставляйте в нужные места. Не берусь прогнозировать, но думаю, что минимум двукратный выигрыш обеспечен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 19:22 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
mds_world, спасибо, дельный совет, не подумал об этом. Вы правы, получается несколько тысяч раз происходит вычисление этих контант. P.S. Вопрос попутно (для общего развития): почему тот же самый код на VB.NET выполняется на порядок (в 10 раз!) быстрее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 19:34 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
sademДоброго времени суток всем! Подскажите, можно ли как-нибудь быстро вычислить интеграл в VB6 с большой точностью от функции, заданной кусочно? Конкретно приведенный интеграл численно вычислять нужно когда InFn>5.8 * 10 ^ 3 or InFv<5 * 10 ^ 4 - в остальных случаях - вычисляется аналитически + значение в диапазоне 5.8 * 10 ^ 3 To 5 * 10 ^ 4. В общем случае, имеет смысл предвычислять значение интегралов на кусочках, а потом, когда кусочки целиком попадают в пределы интегрирования, сразу добавлять значения интегралов на них. Скорость вычисления на VB6 сильно ограничена тем, что байт-код интерпретируется, а в дотнет - он (IL) сначала предкомпилируется. Если вы используете компилятор в нативный код, скорость будет еще больше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 20:06 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
sademAntonariy, я же привел часть программы (только функцию). Чуть выше в теле программы есть запись Public fx, x As Single (это же и есть объявление, или я уже что-то не понимаю?!). Но все же попробывал сделать как посоветовал Konst_One, определил входящие As Single, прирост в скорости не сильно заметен (может быть на пару секунд максимум ускорение и произошло, секундомером не засекал). Но все равно вычисление всех пяти интегралов идет около 1 минуты!Во - первых, нужно приводить не огрызки, а максимально полный код, особенно в случаях оптимизации. Во-вторых, Public fx, x As Single = fx as Variant, x as Single. В-третьих, Log принимает Double, а не Single. Ну и в-четвертых, научитесь оформлять код подобающе, не все, как mds_world, испытывают кайф выискивая крупицы смысла в монотонной простыне текста. Возведение в степень медленная операция, а уж в цикле, который невооруженным взглядом не видно… 10 * 10 * 10 неиллюзорно быстрее, чем 10 ^ 3. mds_worldНе берусь прогнозировать, но думаю, что минимум двукратный выигрыш обеспечен.Много более, чем двукратный. А аналогичный код на .NET выполняется быстрее потому что его разработчики учли типиные косяки кодеров, которые вы в полный рост продемонстрировали (я имею ввиду скомпилированный код). Грамотно оптимизированный VB6-код в половине случаев оставляет позади .NET. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 22:18 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
Antonariy, думаю вряд ли кто-то захочет разбираться в коде длиной несколько сотен строчек (если я выложу весь код), да и описательная часть интерфейса никому не нужна. Про второе спасибо, оказывается с этим просчитался. По третьему, мне без разницы, Log у меня все равно не больше 100 принимает значения. А по четвертому пункту - виноват, исправлюсь :) По поводу замены на константы (Log и возведение в степень) - не помогло, скорость вычисления осталась та же (можете сами проверить). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 22:59 |
|
||
|
Как ускорить вычисление инеграла?
|
|||
|---|---|---|---|
|
#18+
sademПо третьему, мне без разницы, Log у меня все равно не больше 100 принимает значения.Не без разницы компилятору — Single в Double все равно конвертировать придется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.03.2009, 23:28 |
|
||
|
|

start [/forum/topic.php?fid=60&fpage=166&tid=2161288]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
21ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 353ms |

| 0 / 0 |
