LINUX.ORG.RU

[haskell] Покритикуйте программу численного интегрирования

 


0

0

Метод (правых) прямоугольников:

equidistantPoints a b n = [a, a + h .. b]
    where h = (b - a) / n

squareIntegrateR f a b n =
    (sum (map f (tail (equidistantPoints a b n)))) * h
    where h = (b - a) / n

main = do
    print ( squareIntegrateR (\x -> cos x) 0 (pi/2) 100000 )
    print ( squareIntegrateR (\x -> x) 0 (pi/2) 10000 )
    print ( x*x/2 ) where x = pi/2

Проверка:

# ghc -o int int.hs && ./int
0.999992145996432
1.2338239201912735
1.2337005501361697

☆☆

Последнее исправление: ip1981 (всего исправлений: 1)

> print ( squareIntegrateR (\x -> cos x) 0 (pi/2) 100000 )

print $ squareIntegrateR cos 0 (pi/2) 100000

print ( squareIntegrateR (\x -> x) 0 (pi/2) 10000 )

print $ squareIntegrateR id 0 (pi/2) 10000

SV0L0CH
()

1. вместо

squareIntegrateR f a b n

должен быть

integral f a b method

а уже method должен содержать информацию о методе, n в случае прямоугольников и т.д.

2. метод прямоугольников — тупизм, т.к. метод трапеций на порядок точнее и вычислений столько же

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>метод прямоугольников — тупизм, т.к. метод трапеций на порядок точнее и вычислений столько же

Молодец, садись, пять =) А метод Симпсона еще точнее =)

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>integral f a b method

а уже method должен содержать информацию о методе, n в случае прямоугольников и т.д.

Да в сущности ведь и нет разницы между

integral f a b method

и

integralMethod f a b

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

>>А метод Симпсона еще точнее

У него сетка в два раза плотнее, и вычислений больше.

Даже при равной же сетке с ходу не оценить, кто точнее, зависит от конкретной функции.

mclaudt
()
Ответ на: комментарий от Waterlaz

> Молодец, садись, пять =) А метод Симпсона еще точнее =)

совсем читать разучился? там вычислений больше.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от SV0L0CH

Да, в этом примере так короче, \x -> ... --- общий случай и более наглядный.

ip1981 ☆☆
() автор топика
Ответ на: комментарий от SV0L0CH

По моему чувству прекрасного (то есть, спорить бесполезно), писать (f.g.h) x стоит, если все функции имеют только по одному аргументу.

ip1981 ☆☆
() автор топика
Ответ на: комментарий от www_linux_org_ru

[haskell]

Главное не метод, а Хаскель ;-)

ip1981 ☆☆
() автор топика

К левым прямоугольникам легко перейти, заменив tail на init:

squareIntegrateL f a b n =
    (sum (map f (init (equidistantPoints a b n)))) * h
    where h = (b - a) / n

ip1981 ☆☆
() автор топика
Ответ на: комментарий от SV0L0CH

> > (sum (map f (tail (equidistantPoints a b n)))) * h

(sum.(map f).tail.equidistantPoints) — но так в основном я пишу

У аппликации функций приоритет выше, чем у композиции функций, т.е. скобки вокруг map f не нужны. И у тебя тут ошибка.

(sum (map f (tail (equidistantPoints a b n)))) * h

Можно записать как:

(sum . map f . tail $ equidistantPoints a b n) * h

suzuki
()

А вот и метод трапеций:

trapezeIntegrate f a b n =
    ((sum (map f ((tail . init) xs))) + t) * h
    where
        xs = equidistantPoints a b n
        t = ((f a) + (f b))/2
        h = (b - a) / n

ip1981 ☆☆
() автор топика
Ответ на: комментарий от suzuki

Похоже на то, надо иногда проверять что пишеш в интерпретаторе и не писать при этом на двух других языках :-/

SV0L0CH
()
Ответ на: комментарий от SV0L0CH

Не похоже, я так и есть. Ты попробовал скрестить ежа и ужа.

Глядя на

(.) :: (b -> c) -> (a -> b) -> a -> c

сразу видно нужный вариант:

(sum . map f . tail . equidistantPoints a b) n * h

suzuki
()
Ответ на: комментарий от suzuki

>Скобки (f a) не нужны

Я тут походу пытаюсь scheme асилить, уже начинает сказыватся. Видать, пора завязвывать...

SV0L0CH
()
Ответ на: комментарий от mclaudt

>У него сетка в два раза плотнее, и вычислений больше.

Даже при равной же сетке с ходу не оценить, кто точнее, зависит от конкретной функции

Всегда зависит от конкретной функции. Могу предложить функцию, котторую метод трапеций интегрирует хуже метода прямоугольников.

совсем читать разучился? там вычислений больше.

это не правда :p

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> 2. метод прямоугольников — тупизм, т.к. метод трапеций на порядок точнее и вычислений столько же

доказательства будут? есть мнение, что метод средних прямоугольников точнее метода трапеций :) более того, если открыть гугл, то можно найти этому подтверждение.

qnikst ★★★★★
()
h = (b - a) / n 
:t (3-2)/10
(3-2)/10 :: (Fractional t) => t

я пока в хацкеле почти не разбираюсь, но это нормально что h имеет тип Fractional и не приведёт ли к огромным потерям в скорости работы? На точность плевать ибо погрешность метода >> погрешности из-за неточности Double.

qnikst ★★★★★
()
Ответ на: комментарий от Shimuuar

Я не о формальной стороне дела, а о типографской.

ip1981 ☆☆
() автор топика
Ответ на: комментарий от qnikst

> доказательства будут?

у трапеций погрешность порядка 1/(n*n), у прямоугольников порядка 1/n

есть мнение, что метод средних прямоугольников точнее метода трапеций :) более того, если открыть гугл, то можно найти этому подтверждение.

это я уже сходу не вспомню, давай ссылку, но не гугл

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>> Могу предложить функцию, котторую метод трапеций интегрирует хуже метода прямоугольников.

предложи

Понятно, что при определенной сетке есессно.

f(x) = k, x \in [0.1+k, 1.1+k)

Интеграл от 0 до 10 сетка 0,1,2...

При большом желании можно и непрерывную придумать.

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> у трапеций погрешность порядка 1/(n*n), у прямоугольников порядка 1/n

пожалуйста, на досуге поищи пруф. выкладывать тут не обязательно. всё таки тут не math-nazi сидят.

это я уже сходу не вспомню, давай ссылку, но не гугл

ссылку не дам но вборшу (тех поймёшь)

погрешности на каждом отрезке:

прямоугольники: |\psi_i|\le \frac{h^3}{24}M_{2,i}

трапеция: |\psi_i|\le \frac{M_{2,i}h^3}{12}

т.е. трапеция в 2 раза хуже.

qnikst ★★★★★
()
Ответ на: комментарий от Waterlaz

> Понятно, что при определенной сетке есессно. f(x) = k, x \in [0.1+k, 1.1+k) Интеграл от 0 до 10 сетка 0,1,2... При большом желании можно и непрерывную придумать.

Ты думаешь после такого примера тебя здесь будут после этого всерьез воспринимать? Давай непрерывную хотя бы с производной почти везде.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от qnikst

> пожалуйста, на досуге поищи пруф. выкладывать тут не обязательно. всё таки тут не math-nazi сидят.

перевод на русский: я математику не знаю, но буду нести всякую чушь, пруфы приводить тоже не буду

пруфы вот http://ru.wikipedia.org/wiki/Формула_трапеций http://en.wikipedia.org/wiki/Numerical_integration

если для прямоугольников сам не можешь вывести формулу остаточного члена, то молчи уж лучше

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

обидно из-за википедии искать становится сложнее 1). http://www.machinelearning.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D...

2). Подробный вывод по действиям: http://petrsu.ru/Chairs/IMO/Complex/part3/part36_a.htm

выводы результатов там написаны, и не отличаются от того, что я написал постом выше.

И очень хочется ответить тебе твоей же цитатой «если для прямоугольников сам не можешь вывести формулу остаточного члена, то молчи уж лучше».

qnikst ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

sin(x) x \in [0,\pi] при 2 точках. Метод средних прямоугольников даст 1/2 метод трапеции 0. Аналогично будет для плохих функций.

Метод трапеций и метод прямоугольников апроскимируют функцию прямыми у них не может быть разный порядок погрешности :)

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

> sin(x) x \in [0,\pi] при 2 точках.

после этого ты хочешь чтобы с тобой серьезно разговаривали? даю шанс — приведи нормальный пример

Метод трапеций и метод прямоугольников апроскимируют функцию прямыми у них не может быть разный порядок погрешности :)

посчитай интерграл от f(x)=x на отрезке [0,1] методом трапеций, левых и правых прямоугольников и удивись

насчет средних могу сказать только что навскидку это то же, что и трапеции, но точнее надо считать

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от qnikst

>Метод трапеций и метод прямоугольников апроскимируют функцию прямыми у них не может быть разный порядок погрешности :)

Метод прямоугольников апроксимирует константыми функциями. Метод трапеций - прямыми.

Waterlaz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>Ты думаешь после такого примера тебя здесь будут после этого всерьез воспринимать? Давай непрерывную хотя бы с производной почти везде.

Трололо, такое трололо :D

Глупенький, указанная мной функция разрывна в конечном числе точек не совпадающих с точками выбранной сетки. А значит я могу как угдно близко приближать(в смысле что интеграл модуля разницы функций стремится к нулю) ее непрерывной бесконечно раз дифференцируемой функцией притом совпадающей с исходной в точках сетки.

ЗЫ твои потуги повыеживаться забавны =)

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

> указанная мной функция разрывна в конечном числе точек не совпадающих с точками выбранной сетки. А значит я могу как угдно близко приближать(в смысле что интеграл модуля разницы функций стремится к нулю) ее непрерывной бесконечно раз дифференцируемой функцией притом совпадающей с исходной в точках сетки.

твой пример должен быть применим при сетке не с придуманным специально для этой функции n, а с любым (возможно достаточно большим) n

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

читай внимательнее, с самого начала я писал про средние. В ссылках, что я дал есть вся процедура расчёта, в моём посте выше есть результат.

qnikst ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

>твой пример должен быть применим при сетке не с придуманным специально для этой функции n, а с любым (возможно достаточно большим) n

Ну я сразу говорил, что при уменьшении шага сетки естественно прямоугольники отсосут.

Waterlaz ★★★★★
()
Ответ на: комментарий от qnikst

> читай внимательнее, с самого начала я писал про средние. В ссылках, что я дал есть вся процедура расчёта, в моём посте выше есть результат.

Чисто для проверки, знаешь ты ли или копипастишь, можно было бы тебя заставить самому таки написать соответсвующий пример, но мне лень.

Допустим f(x)=x*x дает одинаковый порядок малости и вдвое худшую точность при трапециях, чем при средних прямоугольниках.

И говоря про «прямоугольники — тупизм», я имел в виду метод «правых прямоугольников», как это у топикстартера.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Waterlaz

> Конечно может

я думал ты че-нить поинтереснее придумаешь, типа x*sin(1/x) на [0,1]

www_linux_org_ru ★★★★★
()

Ты как, с хаскелем уже закончил? Давай что-нибудь новое, а тут уже оффтопик пошёл, не интересно как-то ;)

suzuki
()

Прочитал заголовок и подумал, что тут будет что-то типа вычисления по узлам Гаусса или что-то сложное для разбора метод :(

1. Сделай из двух подпрограмм одну

2. добавь переменную и присвой ей шаг, считаться будет быстрее.

З.ы. метод Симпсона точнее чем метод прямоугольников.

Zodd ★★★★★
()
Ответ на: комментарий от suzuki

Это вы мне? Скоро будет новое, но на Хаскеле.

Я пока тренируюсь, и моих знаний Хаскея не достаточно, чтобы выразить свои мысли ;-)

ip1981 ☆☆
() автор топика
Ответ на: комментарий от ip1981

> Это вы мне? Скоро будет новое, но на Хаскеле.

Ммм, нет ли тут косяка в предложении?

и моих знаний Хаскея не достаточно, чтобы выразить свои мысли ;-)

Пиши, как можешь, тебе помогут разобраться. Хаскель в массы, D - на доработку! ;0

Например, как-нибудь так:

[code]

myFunction :: MyType AnotherType -> Type1 -> MyType2 AnotherType2 myFunction = undefined

{- code that uses myFunction -} [/code]

С вопросом: «а как бы мне сделать вот это и это?»

suzuki
()
Ответ на: комментарий от www_linux_org_ru

> Чисто для проверки, знаешь ты ли или копипастишь, можно было бы тебя заставить самому таки написать соответсвующий пример, но мне лень.

Порядки погрешностей и то как они соотносятся - знаю. Саму формулу скопипастил, т.к. помнить её мне не нужно, а выводить ради непонятно чего не вижу смысла. Уже повыводил пару лет назад при сдаче программирования.

Допустим f(x)=x*x дает одинаковый порядок малости и вдвое худшую точность при трапециях, чем при средних прямоугольниках.

Что значит допустим? В приведённых ссылках есть результат и вывод того, что априорное значение погрешности вычисления методом ср. прямоугольников в 2 раза меньше, чем трапеции (на равномерном разбиении). Если есть пренетзии к доказательтву можете писать их и что-либо выводить.

И говоря про «прямоугольники — тупизм», я имел в виду метод «правых прямоугольников», как это у топикстартера.

Ок согласен с утверждением. Причепился к тому, что предлагался метод, который не лучше другого, более простого в реализации.

qnikst ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.