Position du soleil, équation du temps: fausse de 27 jours

J'essaie d'améliorer l' algorithme de calcul de la position du soleil de l'observatoire de la marine américaine. , en l’écrivant de manière plus simple, là où tous les nombres utilisés ont été correctement identifiés - afin que les gens normaux puissent également le comprendre.

Mais d'une manière ou d'une autre, l'équation du temps est décalée de 27 jours. Peut-être que quelqu'un ici peut repérer ce qui ne va pas?

Essai:

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.

Nouvel algorithme:

# 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

Merci!

Tapis

1
Pourriez-vous poster l'ancien code, cela (je présume) fonctionne?
ajouté l'auteur Beta, source
@ ja72: ressemble à Ruby.
ajouté l'auteur Mechanical snail, source
Marquez la langue utilisée et envisagez de migrer vers codereview.stackexchange.com .
ajouté l'auteur ja72, source
@ ja72 codereview est pour le code de travail , n'est-ce pas?
ajouté l'auteur AakashM, source
Je pense que votre code est mélangé d'une certaine manière: la valeur de l'excentricité de la Terre est de 0,01671 (voir Wikipedia). Vous utilisez exactement cette valeur pour la réfraction atmosphérique et la convertissez de degrés en radians. C'est n'importe quoi.
ajouté l'auteur Curd, source
@ ja72: Ce n'est pas vraiment une question de ruby cependant.
ajouté l'auteur Molvær, source

3 Réponses

Certains de mes codes.

# 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

Où est-il utilisé?

# 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
ajouté

Ici:

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

vous mélangez des unités. suns_mean_longitude est exprimé en radians, de même que SUNS_GEODETIC_PRECESSION (et donc le second terme également), mais EARTHS_ORBITAL_ECCENTRICITY est 0.020 . forte> degrés .

Aditionellement:

EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = degrees_to_radians 0.01671

devrait juste être

EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = 0.01671

Je pense, puisque ceci est utilisé dans une formule qui détermine une distance .

De plus en plus,

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

Je n'ai pas vérifié quelles unités cette fonction atan2 est retournée - êtes-vous sûr que ce sont des degrés, qu'il faudrait diviser par 15 pour donner un sens?

Il peut y avoir d'autres problèmes; ce ne sont que ceux que je peux voir.

1
ajouté
Correct! ruby-doc.org/core-1.9.3/Math.html#method-c-atan2 Lorsque la plage de retour est exprimée sous forme de valeurs PI, assurez-vous qu'elles sont exprimées en radians. Envisagez d'utiliser ce type de formule également y0 = sine_al_Sun (ta) * cosine_to_Earth (ta) al est suns_apparent_ecliptic_longitude et to est la vraie obliquité et non la longitude. C'est l'angle d'inclinaison de la Terre par rapport au pôle céleste. 180.0 + rad_to_deg (atan2 (-y0, -cosine_al_Sun (ta))) Cela aidera à conserver la valeur de retour dans la plage appropriée. Comme l'a dit l'homme, ne mélangez pas les pommes avec les oranges. deg rad
ajouté l'auteur Douglas G. Allen, source

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

Selon l'article, vous devrez peut-être utiliser la classe BigDecimal pour vos opérations en virgule flottante. En fait, je n’ai pas suivi votre programme, c’est juste une supposition.

0
ajouté