Программное обеспечение астрономии предсказывает местоположение Солнца, принимая прогнозы JPL о том, где будут находиться Земля и Солнце, которые JPL выражает в виде серии полиномов, охватывающих определенные диапазоны дат. На вопрос "когда солнце будет на азимуте z?" спрашивает, когда три разных полинома, каждый из которых изменяется с разной скоростью (полином для Солнца, для барицентра Земля-Луна, вращающегося вокруг Солнца, и Земля, вращающаяся вокруг барицентра), окажутся различиями между две позиции под точно определенным углом.
И оказывается, что эта задача относится к классу «грубых» математических задач - или, как говорят профессионалы, «задач без решения в замкнутой форме». Но мне нравится ваше слово «грубый», потому что оно очень хорошо улавливает то, что чувствует большинство из нас, когда мы обнаруживаем, что большая часть мира должна решаться методом проб и ошибок, а не просто давать нам ответ.
К счастью, достаточно обширный научный образец является «грубым» в том смысле, что существуют стандартные способы спросить, «когда эта большая сложная функция достигнет точного значения z?» Если вы сможете установить и опробовать SciPy, все более популярную научную библиотеку для Python, вы обнаружите, что в ней есть целый набор подпрограмм, которые подкрадываются к решениям, каждая из которых использует свою тактику. Другой ответчик уже определил одну такую тактику - сокращение вдвое пространства поиска с каждым испытанием - но это, как правило, самый медленный (хотя в некоторых крайних случаях и самый безопасный) подход; вот еще несколько:
http://docs.scipy.org/doc/scipy/reference/optimize.html
Создайте небольшую функцию, которая возвращает «насколько далеко» азимут Солнца - это время t
от желаемого азимута, где функция, наконец, вернет ноль, когда азимут точно правильный, например:
def f(t):
...
return desired_az - sun.az
Затем попробуйте одну из «скалярных функций для поиска корней» с этой страницы SciPy. Функция bisect()
будет, как и предлагает другой ответчик, сокращать пространство поиска вдвое, чтобы сузить круг вопросов. Но я предполагаю, что вы найдете метод Ньютона гораздо менее «грубым» и гораздо более быстрым - попробуйте newton()
или brentq()
и посмотрите, что произойдет!
person
Brandon Rhodes
schedule
25.02.2013