Игорь Пашев - Численное интегрирование на Хаскеле

Jan. 10th, 2010

02:51 pm - Численное интегрирование на Хаскеле

Previous Entry Add to Memories Tell A Friend Next Entry

Методы прямоугольников, трапеций, Симпсона.
Цель — освоиться с Хаскелем.

-- Правые прямоугольники
squareIntegrateR f a b n =
    (sum (map f [a + h, a + 2*.. b])) * h
    where h = (b - a) / n

-- Левые прямоугольники
squareIntegrateL f a b n =
    (sum (map f [a, a + h .. b - h])) * h
    where h = (b - a) / n

-- Средние прямоугольники
squareIntegrate f a b n =
    (sum (map f [a + h/2, a + h/2 + h .. b - h/2])) * h
    where h = (b - a) / n

-- Трапеции
trapezeIntegrate f a b n =
    ((sum (map f [a + h, a + 2*.. b - h])) + t) * h
    where
        t = (f a + f b)/2
        h = (b - a) / n

-- Симпсон
simpsonIntegrate f a b n =
    (s + s4 + s2) * h / 6
    where
        s  = f a + f b
        s4 = 4 * (sum . map f $ [a + h/2, a + h/2 + h .. b - h/2])
        s2 = 2 * (sum . map f $ [a + h,   a + 2*h     .. b - h])
        h  = 2 * (b - a) / n -- кол-во вычислений такое же

-- Функции для проверки
testcases = [
--             функция      a   b      n    ответ
    ("x",     \-> x,      01,    100,   1/2),
    ("x^2",   \-> x^2,    12,    100,   7/3),
    ("cos x"\-> cos(x), 0, pi/2100,   1.0),
    ("sin x"\-> sin(x), 0, pi/2100,   1.0),
    ("exp x"\-> exp(x), 01,    100,   exp(1- 1),
    ("x*sin x"\-> x*sin(x), 02*pi, 100-6.283185306023805)
          ]

-- Процедура проверки
maketest [] = do return ()
maketest ((name, f, a, b, n, r):ts) = do
    putStrLn ""
    putStrLn $ "-- " ++ name ++ " от " ++ show a ++ " до "
            ++ show b ++ ", n = " ++ show n ++ ", равно " ++ show r
    putStrLn $ "Правые  прямоугольники: " ++ show (squareIntegrateR f a b n)
    putStrLn $ "Левые   прямоугольники: " ++ show (squareIntegrateL f a b n)
    putStrLn $ "Средние прямоугольники: " ++ show (squareIntegrate  f a b n)
    putStrLn $ "Формула трапеций:       " ++ show (squareIntegrateR f a b n)
    putStrLn $ "Формула Симпсона:       " ++ show (simpsonIntegrate f a b n)
    maketest ts


main = do
    maketest testcases




Проверка:

# ghc -o int int.hs && ./int

-- x от 0.0 до 1.0, n = 100.0, равно 0.5
Правые  прямоугольники: 0.5050000000000003
Левые   прямоугольники: 0.4950000000000003
Средние прямоугольники: 0.5000000000000003
Формула трапеций:       0.5050000000000003
Формула Симпсона:       0.5000000000000003

-- x^2 от 1.0 до 2.0, n = 100.0, равно 2.3333333333333335
Правые  прямоугольники: 2.348350000000002
Левые   прямоугольники: 2.318350000000002
Средние прямоугольники: 2.3333250000000008
Формула трапеций:       2.348350000000002
Формула Симпсона:       2.3333333333333344

-- cos x от 0.0 до 1.5707963267948966, n = 100.0, равно 1.0
Правые  прямоугольники: 0.9921254566056366
Левые   прямоугольники: 1.0078334198735852
Средние прямоугольники: 1.0000102809119091
Формула трапеций:       0.9921254566056366
Формула Симпсона:       1.0000000003382377

-- sin x от 0.0 до 1.5707963267948966, n = 100.0, равно 1.0
Правые  прямоугольники: 1.0078334198735803
Левые   прямоугольники: 0.9921254566056313
Средние прямоугольники: 1.0000102809119036
Формула трапеций:       1.0078334198735803
Формула Симпсона:       1.0000000003382354

-- exp x от 0.0 до 1.0, n = 100.0, равно 1.718281828459045
Правые  прямоугольники: 1.7268875565927133
Левые   прямоугольники: 1.7097047383081228
Средние прямоугольники: 1.718274668972309
Формула трапеций:       1.7268875565927133
Формула Симпсона:       1.718281828554505

-- x*sin x от 0.0 до 6.283185307179586, n = 100.0, равно -6.283185306023805
Правые  прямоугольники: -6.281118086046078
Левые   прямоугольники: -6.281118086046067
Средние прямоугольники: -6.284218968755679
Формула трапеций:       -6.281118086046078
Формула Симпсона:       -6.283185851470418


P. S. GHC 6.12.1 прекрасно собирается из исходников и устанавливается как надо и куда скажешь :-)

Tags: , ,
(Оставить комментарий)