Позиція Сонця, рівняння часу: НЕПРАВИЛЬНО ДО 27 ДНІВ

Я намагаюся покращити алгоритм обчислення позиції сонця , написавши це простішим способом, де всі використовувані номери були належним чином ідентифіковані, - тому звичайні люди це також можуть зрозуміти.

Але так чи інакше, рівняння часу вимкнено на 27 днів. Може хтось тут може визначити, що не так?

Тестовий пробіг:

1) Failure:
test_equation_of_time(TestSolarCalculations):
Expected 2011-10-01 10:23:00 UTC, not 2011-10-28 10:59:31 UTC.

2) Failure:
test_suns_declination(TestSolarCalculations):
Expected -3.18, not -3.2087920449753007.

Новий алгоритм:

# Constants for J2000.0/1 Jan 2000 12:00Z:
#
EPOCHS_JULIAN_DATE = 2451545
ANOMALISTIC_YEAR_IN_DAYS = 365.259636
TROPICAL_YEAR_IN_DAYS = 365.2421897
SUNS_MEAN_ANOMALY_AT_EPOCH = degrees_to_radians 357.5291
SUNS_MEAN_LONGITUDE_AT_EPOCH = degrees_to_radians 280.459
SUNS_GEODETIC_PRECESSION = degrees_to_radians 1.915
EARTHS_ORBITAL_ECCENTRICITY = 0.020
EARTHS_ADJUSTED_AVERAGE_RADIUS_IN_AU = 1.00014
EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = degrees_to_radians 0.01671
EARTHS_ECLIPTIC_MEAN_OBLIQUITY = degrees_to_radians 23.439
EARTHS_ECLIPTIC_OBLIQUITY_CHANGE_RATE = degrees_to_radians 0.00000036

def days_from_epoch
  @todays_julian_date - EPOCHS_JULIAN_DATE
end

def suns_daily_mean_anomaly_change_rate
  degrees_to_radians(360/ANOMALISTIC_YEAR_IN_DAYS)
end

def suns_mean_anomaly
  SUNS_MEAN_ANOMALY_AT_EPOCH + suns_daily_mean_anomaly_change_rate * days_from_epoch
end

def suns_daily_mean_longitude_change_rate
  degrees_to_radians(360/TROPICAL_YEAR_IN_DAYS)
end

def suns_mean_longitude
  SUNS_MEAN_LONGITUDE_AT_EPOCH + suns_daily_mean_longitude_change_rate * days_from_epoch
end

def suns_apparent_ecliptic_longitude
  suns_mean_longitude + SUNS_GEODETIC_PRECESSION * sin(suns_mean_anomaly) + EARTHS_ORBITAL_ECCENTRICITY * sin(2 * suns_mean_anomaly)
end

def suns_distance_from_earth_in_au
  EARTHS_ADJUSTED_AVERAGE_RADIUS_IN_AU - EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION * cos(suns_mean_anomaly) - (EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION ^ 2/2) * cos(2 * suns_mean_anomaly)
end

def earths_ecliptic_mean_obliquity
  EARTHS_ECLIPTIC_MEAN_OBLIQUITY - EARTHS_ECLIPTIC_OBLIQUITY_CHANGE_RATE * days_from_epoch
end

def suns_right_ascension
  atan2(cos(suns_apparent_ecliptic_longitude) * sin(suns_apparent_ecliptic_longitude), cos(suns_apparent_ecliptic_longitude))/15
end

# Time.utc(Time.now.year) => 2011-01-01 00:00:00 UTC
#
def equation_of_time
  Time.utc(Time.now.year) + (radians_to_degrees(suns_mean_longitude)/15 - suns_right_ascension) * 60 * 60 * 24
end

def suns_declination
  radians_to_degrees(asin(sin(earths_ecliptic_mean_obliquity) * sin(suns_apparent_ecliptic_longitude)))
end

Дякую!

Мати

1
Не могли б ви опублікувати старий код, що (я вважаю) працює?
додано Автор Beta, джерело
@ ja72: виглядає як Ruby.
додано Автор Mechanical snail, джерело
Будь-ласка, позначте мову, що використовується, і перейдіть на codereview.stackexchange.com .
додано Автор ja72, джерело
@ ja72 codereview для робочого коду, чи не так?
додано Автор AakashM, джерело
Я думаю, що ваш код змішаний якось: величина земної ексцентриситет становить 0.01671 (див. Вікіпедія). Ви використовуєте саме це значення для атмосферної рефракції і перетворюєте його з градусів на радіани. Це дурниця.
додано Автор Curd, джерело
@ ja72: Це, по суті, не є ruby питання.
додано Автор Molvær, джерело

3 Відповіді

Деякий з мого коду.

# From angles.rb:
# eccentricity of elliptical Earth orbit around Sun # Horner calculation method def eccentricity_Earth( ta = A2000 ) ta = check_jct_zero( ta ) # 0.016708617 - ta[ 0 ] * ( 0.000042037 + ta[ 0 ] * 0.0000001235 ) [-0.0000001235, -0.000042037, 0.016708617].inject(0.0) {|p, a| p * ta[0] + a} end alias_method :eccentricity_earth_orbit, :eccentricity_Earth

From: Equation of Time ruby gem

Де вона використовується?

# From angles.rb:
# equation of centre # added to mean anomaly to get true anomaly. def center( ta = A2000) ta = check_jct_zero( ta ) sine_1M = sin( 1.0 * deg_to_rad( @ma ) ) sine_2M = sin( 2.0 * deg_to_rad( @ma ) ) sine_3M = sin( 3.0 * deg_to_rad( @ma ) ) sine_4M = sin( 4.0 * deg_to_rad( @ma ) ) sine_5M = sin( 5.0 * deg_to_rad( @ma ) ) e = eccentricity_Earth( ta ) rad_to_deg( sine_1M * ( 2.0 * e - e**3/4.0 + 5/96.0 * e**5 ) + sine_2M * ( 5/4.0 * e**2 - 11/24.0 * e**4 ) + sine_3M * ( 13/12.0 * e**3 - 43/64.0 * e**5 ) + sine_4M * 103/96.0 * e**4 + sine_5M * 1097/960.0 * e**5 ) # sine_1M *( 1.914602 - ta[ 0 ] * ( 0.004817 + ta[ 0 ] * 0.000014 )) + # sine_2M *( 0.019993 - ta[ 0 ] * 0.000101 ) + # sine_3M * 0.000289 end alias_method :equation_of_center, :center
1
додано

Тут:

def suns_apparent_ecliptic_longitude
  suns_mean_longitude 
  + SUNS_GEODETIC_PRECESSION * sin(suns_mean_anomaly) 
  + EARTHS_ORBITAL_ECCENTRICITY * sin(2 * suns_mean_anomaly)
end

ви змішуєте одиниці suns_mean_longitude - це радіани, як і SUNS_GEODETIC_PRECESSION (і тому це другий термін), але EARTHS_ORBITAL_ECCENTRICITY - 0.020 < strong> градусів .

Додатково:

EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = degrees_to_radians 0.01671

повинен бути просто

EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = 0.01671

Я думаю, оскільки це використовується у формулі, яка визначає відстань .

Крім того, додатково

def suns_right_ascension
  atan2(cos(suns_apparent_ecliptic_longitude) * sin(suns_apparent_ecliptic_longitude), cos(suns_apparent_ecliptic_longitude))/15
end

Я не перевірив, які одиниці ця функція atan2 повертає - ви впевнені, що це градуси, які слід мати для того, щоб розбити на 15, щоб мати сенс?

Можливі інші проблеми; це лише ті, що я бачу.

1
додано
Правильно! ruby-doc.org/core-1.9.3/Math.html#method-c-atan2 Коли коли-небудь діапазон повернення виражається як значення PI, то переконайтеся, що вони знаходяться в радіанах. Подумайте про використання цього типу формул також y0 = sine_al_Sun (ta) * cosine_to_Earth (ta) al - suns_apparent_ecliptic_longitude, а це істинний нахил не довгота. Це кут нахилу Землі щодо Небесного Полюса. 180.0 + rad_to_deg (atan2 (-y0, -cosine_al_Sun (ta))) Це допоможе зберегти повернення значення у відповідному діапазоні. Як сказав чоловік, не змішайте яблука з апельсинами. град рад
додано Автор Douglas G. Allen, джерело

May be it is an issue with the precision of ruby floating point numbers, not an issue with your program's logic? I haven't used ruby, but it seems there are some issues in ruby floating point operations exists according to thisposts. Issue with precision of ruby math operations

Згідно з повідомленням, вам може знадобитися використовувати клас BigDecimal для операцій з плаваючою комою. Я насправді не пройшов через вашу програму, це просто здогадатися.

0
додано