Advertisement
Guest User

Untitled

a guest
May 26th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.18 KB | None | 0 0
  1. from math import *
  2.  
  3. #Задаем функцию, можно менять
  4. def func(x):
  5.     return  3 / 2 * pow(x, 2) #возвращает f(x)
  6.  
  7.  
  8. def _rectangle_rule(a, b, nseg, frac):
  9.     """Обобщённое правило прямоугольников."""
  10.     dx = 1.0 * (b - a) / nseg
  11.     sum = 0.0
  12.     xstart = a + frac * dx # 0 <= frac <= 1 задаёт долю смещения точки,
  13.                            # в которой вычисляется функция,
  14.                            # от левого края отрезка dx
  15.     npoints = nseg
  16.     for i in range(npoints):
  17.         sum += func(xstart + i * dx)
  18.  
  19.     return sum * dx
  20.  
  21. def left_rectangle_rule(a, b, nseg):
  22.     """Правило левых прямоугольников"""
  23.     return _rectangle_rule(a, b, nseg, 0.0)
  24.  
  25. def right_rectangle_rule(a, b, nseg):
  26.     """Правило правых прямоугольников"""
  27.     return _rectangle_rule(a, b, npoints, 1.0)
  28.  
  29. def midpoint_rectangle_rule(a, b, nseg):
  30.     """Правило прямоугольников со средней точкой"""
  31.     return _rectangle_rule(a, b, nseg, 0.5)
  32.  
  33. def Num_1(a, b, rtol = 1e-8, nseg0 = 1):
  34.     """Правило трапеций
  35.           rtol - желаемая относительная точность вычислений
  36.           nseg0 - начальное число отрезков разбиения"""
  37.     nseg = nseg0
  38.     old_ans = 0.0
  39.     dx = 1.0 * (b - a) / nseg #подсчитаем длинну разбиения
  40.     ans = 0.5 * (func(a) + func(b)) #подсчитаем интеграл на границах
  41.     for i in range(1, nseg):
  42.         ans += func(a + i * dx) #в цикле подсчитаем суммарную площадь всех прямоугольников, на которые разбили нушу функцию
  43.  
  44.     ans *= dx
  45.     err_est = max(1, abs(ans))
  46.     while (err_est > abs(rtol * ans)): #если нам не хватило точности, то воспользуемся методом средних прямоугольников
  47.         old_ans = ans #посмотрим на старый ответ
  48.         ans = 0.5 * (ans + midpoint_rectangle_rule(a, b, nseg)) #подсчитаем новый
  49.         nseg *= 2
  50.         err_est = abs(ans - old_ans) #ычислим ошибку
  51.  
  52.     return ans
  53.  
  54.  
  55. #аналогично первому пункту (решили задачу в общем виде для элементарных функций)
  56. def Num_2(a, b, rtol = 1e-8, nseg0 = 1):
  57.     nseg = nseg0
  58.     old_ans = 0.0
  59.     dx = 1.0 * (b - a) / nseg
  60.     ans = 0.5 * (func(a) + func(b))
  61.     for i in range(1, nseg):
  62.         ans += func(a + i * dx)
  63.  
  64.     ans *= dx
  65.     err_est = max(1, abs(ans))
  66.     while (err_est > abs(rtol * ans)):
  67.         old_ans = ans
  68.         ans = 0.5 * (ans + midpoint_rectangle_rule(a, b, nseg))
  69.         nseg *= 2
  70.         err_est = abs(ans - old_ans)
  71.  
  72.     return ans
  73.  
  74. print(Num_1(0.0, 2.0, nseg0 = 10, rtol= 0.001))
  75.  
  76. print(Num_1(-3, 5, nseg0= 10))
  77.  
  78. print(Num_2(0, 1))
  79.  
  80. print(Num_1(-1000, 1000, nseg0=1000))
  81.  
  82. print(Num_2(-1000, 20000, nseg0=10))
  83.  
  84. print(Num_2(1.0, 3.0, nseg0 = 1000))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement