#python
Вопрос:
Я пытался решить эту бесконечную сумму с заданной точностью. Вы можете увидеть описание на картинке ниже
Вот что я пробовал до сих пор:
import math
def infin_sum(x, eps):
sum = float(0)
prev = ((-1)*(x**2))/2
i = 2
while True:
current = prev ((-1)**i) * (x**(2*i)) / math.factorial(2*i)
if(abs(current - prev) <= eps):
print(current)
return current
prev = current
i =1
Для данного ввода выборки (0,2 для x и точность 0,00001) моя сумма составляет 6,65777777777778 e-05, и, согласно их тестам, она недостаточно близка к правильному ответу
Комментарии:
1. Более стабильным способом его вычисления была бы сортировка по величине абс, а затем суммирование.
Ответ №1:
Вы должны использовать math.isclose() вместо abs() для проверки вашей сходимости (учитывая, что именно так будет проверяться результат). учитывая, что каждая итерация добавляет или вычитает определенный член, дельта между предыдущим и следующим (Si-1 против Si) будет равна последнему добавленному члену (поэтому вам не нужно отслеживать предыдущее значение).
Этот бесконечный ряд почти совпадает с косинусом (было бы так, если бы я начал с нуля), поэтому вы можете проверить свой результат math.cos(x)-1
. Кроме того, я нахожу странным, что проверка ожидаемого результата фиксируется с точностью до 0,0001, но ввод образца указывает точность 0,00001 (я предполагаю, что более точный результат будет в пределах 0,0001, но тогда проверка на самом деле не проверяет правильность вывода с учетом входных данных?)
from math import isclose
def cosMinus1(x,precision=0.00001):
result = 0
numerator = 1
denominator = 1
even = 0
while not isclose(numerator/denominator,0,abs_tol=precision): # reach precision
numerator *= -x*x # /- for even powers of x
even = 2
denominator *= even * (even-1) # factorial of even numbers
result = numerator / denominator # sum of terms
return result
print(cosMinus1(0.2))
# -0.019933422222222226
import math
expected = math.cos(0.2)-1
print(expected, math.isclose(expected,cosMinus1(0.2),abs_tol=0.0001))
# -0.019933422158758374 True
Ответ №2:
Поскольку тень-не очень хорошая идея sum
, у вас была правильная идея назвать ее current
, но вы не инициализировали current
float(0)
ее и забыли подвести итог. Это ваш код с исправленными проблемами:
def infin_sum(x, eps):
current = float(0)
prev = ((-1) * (x ** 2)) / 2
i = 2
while True:
current = current (((-1) ** i) * (x ** (2 * i))) / math.factorial(2 * i)
if (abs(current - prev) <= eps):
print(current)
return current
prev = current
i = 1
В качестве более общего замечания, печать внутри подобной функции, вероятно, не лучшая идея — это ограничивает возможность повторного использования функции — в идеале вы хотели бы захватить возвращаемое значение и распечатать его вне функции.
Комментарии:
1. Я думаю, что мы оба совершили здесь ошибку. Сумма начинается с i = 1, и в моем коде prev в основном является первым элементом суммы. Поэтому я думаю, что нам нужно добавить случай, когда мы делаем current = prev (уравнение). Я добавил это в свой код, но все равно не работает :/
Ответ №3:
Во-первых, вы не суммируете элементы.
Пересчитывать все с нуля очень расточительно, а точность float
s ограничена.
Вы можете использовать метод Хорнера для уточнения суммы:
import math
def infin_sum(x, eps):
total = float(0)
e = 1
total = 0
i = 1
while abs(e) >= eps:
diff = (-1) * (x ** 2) / (2 * i) / (2 * i - 1)
e *= diff
total = e
i = 1
return total
if __name__ == "__main__":
x = infin_sum(0.2, 0.00001)
print(x)
Ответ №4:
Не забудьте добавить результат, а не заменять его:
prev = current
вместо
prev = current