Проблема с программой для аппроксимации значений sin и косинуса

Я пытаюсь написать программу, которая принимает угол в градусах и аппроксимирует значение sin и cos на основе ряда заданных условий, которые пользователь выбирает. Если вы не знаете, как найти грех и сон. Итак, с учетом сказанного, вот мой текущий код:

import math def main(): print() print("Program to approximate sin and cos.") print("You will be asked to enter an angle and \na number of terms.") print("Written by ME") print() sinx = 0 cosx = 0 x = int(input("Enter an angle (in degrees): ")) terms = int(input("Enter the number of terms to use: ")) print() for i in range(1, terms+1): sinx = sinx + getSin(i, x) cosx = cosx + getCos(i, x) print(cosx, sinx) def getSin(i, x): if i == 1: return x else: num, denom = calcSinFact(i, x) sin = num/denom return sin def getCos(i, x): if i == 1: return 1 else: num, denom = calcCosFact(i, x) cos = num/denom return cos def calcSinFact(i, x): if i % 2 == 1: sign = -1 if i % 2 == 0: sign = +1 denom = math.factorial(i*2-1) num = sign * (x**(i*2-1)) return num, denom def calcCosFact(i, x): if i % 2 == 1: sign = -1 if i % 2 == 0: sign = +1 denom = math.factorial(i*2) num = sign * (x**(i*2)) return num, denom 

Он работает, но если я использую пример, показанный на рисунке выше, я получаю cos = -162527117141.85715 и sin = -881660636823.117. Так ясно, что что-то не работает. На рисунке выше ответы должны быть cos = 0.50000000433433 и sin = 0.866025445100. Я предполагаю, что это то, как я добавляю значения в первом цикле, но я могу ошибаться. Любая помощь приветствуется!

  • вычисление угла между двумя строками в python
  • Что делает оператор ^ (XOR)?
  • Создание уникальных, упорядоченных пифагорейских триплетов
  • 3d Math Library для Python
  • Вычисление стандартного отклонения в потоке
  • Нормализация вектора
  • Загрузите файл по определенному пути, используя Selenium WebDriver
  • Встроенное решение для Django Admin, где Admin содержит ForeignKey для другой модели
  • Изменение размера одного виджета внутри другого виджета в Tkinter
  • Почему расщепление строки медленнее на C ++, чем на Python?
  • Python неживые регулярные выражения
  • Добавить в python путь mac os x
  • 4 Solutions collect form web for “Проблема с программой для аппроксимации значений sin и косинуса”

    Здесь есть несколько вопросов, о которых говорилось в комментариях Рассела Борожева .

    Проблема № 1 заключается в том, что используемые вами формулы

    введите описание изображения здесь

    (см. wikipedia ) ожидать, что x будет в радианах не в градусах. Переход по кругу по кругу равен 360 градусов или 2 * pi, поэтому вы можете конвертировать из градусов в радианы путем умножения на pi / 180, как показано ниже в коде python, чтобы неправильно, а затем правильно получить грех на 90 градусов.

     >>> math.sin(90) 0.8939966636005579 >>> math.sin(90*math.pi/180) 1.0 

    Проблема № 2 – это остальная часть кода. Как отмечено в комментариях, есть некоторые ошибки, и лучший способ их найти – использовать некоторые стратегические заявления print . Тем не менее, вы можете написать свою программу с гораздо меньшим количеством строк кода, а более простые программы, как правило, имеют меньше ошибок и легче отлаживаются, если у них есть проблемы.

    Поскольку это назначение, я не буду делать это за вас, но связанным примером является серия для sinh (x).

    введите описание изображения здесь

    (снова из Википедии)

    Вы можете создавать термины в «одном снимке», используя понимание списка Python. Список может быть print и sum для получения результата, как в приведенной ниже программе

     x = 90 * math.pi / 180 # 90 degrees n = 5 terms = [x**(2*i+1)/math.factorial(2*i+1) for i in range(n)] print terms sinh = sum(terms) print sinh, math.sinh(x) 

    Вывод этой программы

     [1.5707963267948966, 0.6459640975062462, 0.07969262624616703, 0.004681754135318687, 0.00016044118478735975] 2.30129524587 2.30129890231 

    Я подготовил код понимания списка Python непосредственно из математической формулы для суммирования, которая удобно указывать в обозначениях «Сигма» в левой части. Аналогичным образом вы можете создавать sin и cos. Один недостающий ингредиент, который вам нужен, – это знаки в каждой точке серии. Математические формулы говорят вам, что вам нужно (-1) n . Эквивалент Python – (-1)**n , который может быть помещен в соответствующее место в коде понимания списка.

    Во-первых, несколько заметок. Лучше напечатать \n в конце предыдущей печати или в начале следующего, затем пустую print() . Полезно использовать инструмент отладки, использовать модуль logging или просто использовать print и найти ошибку, сравнивая ожидаемые значения с возвращаемыми значениями.

    Вот код, который работает для меня:

     import math def main(): print() print("Program to approximate sin and cos.") print("You will be asked to enter an angle and \na number of terms.") print("Written by ME") print() sinx = 0 cosx = 0 x = int(input("Enter an angle (in degrees): ")) terms = int(input("Enter the number of terms to use: ")) print() x = x / 180.0 * math.pi; # added for i in range(1, terms+1): sinx = sinx + getSin(i, x) cosx = cosx + getCos(i, x) print("Cos:{0}, Sinus:{1}".format(cosx,sinx)); # changed def getSin(i, x): if i == 1: return x else: num, denom = calcSinFact(i, x) sin = float(num)/denom # changed return sin def getCos(i, x): if i == 1: return 1 else: num, denom = calcCosFact(i, x) cos = float(num)/denom # changed return cos def calcSinFact(i, x): if i % 2 == 1: sign = +1 # changed if i % 2 == 0: sign = -1 # changed denom = math.factorial(i*2-1) num = sign * (x**(i*2-1)) return num, denom def calcCosFact(i, x): if i % 2 == 1: sign = +1 # changed if i % 2 == 0: sign = -1 # changed denom = math.factorial(i*2-2) # changed num = sign * (x**(i*2-2)) # changed return num, denom 

    И что я изменил? (Надеюсь, я ничего не забуду)

    1. Ваши sign переменные были неправильными. Как раз наоборот. Поэтому я изменил знаки в условиях.
    2. Возможно, это не обязательно, но я добавил преобразование из int в float, когда вы разделили num на denom .
    3. В соответствии с определением приближения вход x находится в радианах. Поэтому я добавил преобразование из градусов в радианы. x = x / 180.0 * math.pi;
    4. Ваш индекс в calcCosFact был неправильным. Это всегда было выше на 2. (т.е. 4 вместо 2, 8 вместо 6 …)

    Я получил этот результат: введите угол (в градусах): 180 Введите количество используемых терминов: 5 Cos: -0.976022212624, Sinus: 0.00692527070751

    Теперь это должно быть правильно. Я также могу рекомендовать WolphramAlpha, когда вам нужно быстро выполнить некоторую математику.

    Вот улучшенная версия:

     from math import radians import sys # version compatibility shim if sys.hexversion < 0x3000000: # Python 2.x inp = raw_input rng = xrange else: # Python 3.x inp = input rng = range def type_getter(type): def fn(prompt): while True: try: return type(inp(prompt)) except ValueError: pass return fn get_float = type_getter(float) get_int = type_getter(int) def calc_sin(theta, terms): # term 0 num = theta denom = 1 approx = num / denom # following terms for n in rng(1, terms): num *= -theta * theta denom *= (2*n) * (2*n + 1) # running sum approx += num / denom return approx def calc_cos(theta, terms): # term 0 num = 1. denom = 1 approx = num / denom # following terms for n in rng(1, terms): num *= -theta * theta denom *= (2*n - 1) * (2*n) # running sum approx += num / denom return approx def main(): print( "\nProgram to approximate sin and cos." "\nYou will be asked to enter an angle and" "\na number of terms." ) theta = get_float("Enter an angle (in degrees): ") terms = get_int ("Number of terms to use: ") print("sin({}) = {}".format(theta, calc_sin(radians(theta), terms))) print("cos({}) = {}".format(theta, calc_cos(radians(theta), terms))) if __name__=="__main__": main() 

    Заметим, что поскольку ряд Маклорена центрирован на x = 0, значения theta ближе к 0 будут сходиться гораздо быстрее: calc_sin(radians(-90), 5) равно -1.00000354258, но calc_sin(radians(270), 5) составляет -0.444365928238 (примерно в 157 000 раз больше от правильного значения -1,0).

    Можно полностью избежать всех энергетических и факториальных вычислений, используя и комбинируя рекурсивные определения факторной и целочисленной степеней. Дальнейшая оптимизация получается путем вычисления одновременно значений cos и sin, так что мощности вычисляются только один раз.

     PI = 3.1415926535897932384; RadInDeg=PI/180; def getCosSin(x, n): mxx = -x*x; term = 1; k = 2; cossum = 1; sinsum = 1; for i in range(n): term *= mxx term /= k; k+=1 cossum += term term /= k; k+=1 sinsum += term return cossum, x*sinsum def main(): print "\nProgram to approximate sin and cos." print "You will be asked to enter an angle and \na number of terms." x = int(input("Enter an angle (in degrees): ")) terms = int(input("Enter the number of terms to use: ")) print x = x*RadInDeg; cosx, sinx = getCosSin(x,terms) print cosx, sinx if __name__=="__main__": main() 
    Python - лучший язык программирования в мире.