Skip to content

Commit

Permalink
Drop BigDecimal
Browse files Browse the repository at this point in the history
`BigDecimal` was introduced early in the project from my belief that
high accuracy was needed.

It turns out that the number of digits in floats are enough to keep a
precision up to 0.0001 arcseconds in most calculations.

Using `BigDecimal` has a cost over the overall performance of the
library. If it is not absolutely necessary for the calculations, it's
better not to use it.
  • Loading branch information
rhannequin committed Apr 2, 2024
1 parent b92adaf commit 26fb8b4
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 115 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ major one is released.

```rb
angle1 = Astronoby::Angle.from_degrees(90)
angle2 = Astronoby::Angle.from_radians(Astronoby::Angle::PI / 2)
angle2 = Astronoby::Angle.from_radians(Math::PI / 2)
angle3 = Astronoby::Angle.from_hours(12)

angle1 == angle2
Expand Down Expand Up @@ -83,8 +83,8 @@ horizontal_coordinates = sun.horizontal_coordinates(
longitude: longitude
)

horizontal_coordinates.altitude.degrees.to_f
# => 27.50008242057459
horizontal_coordinates.altitude.degrees
# => 27.500082420575094

horizontal_coordinates.altitude.str(:dms)
# => "+27° 30′ 0.2967″"
Expand Down
31 changes: 12 additions & 19 deletions lib/astronoby/angle.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
# frozen_string_literal: true

require "bigdecimal/math"

module Astronoby
class Angle
include Comparable

PRECISION = 14
PI = BigMath.PI(PRECISION)
PI_IN_DEGREES = BigDecimal("180")
MIN_PRECISION = 10
PI_IN_DEGREES = 180.0

FULL_CIRCLE_IN_RADIANS = (2 * PI)
FULL_CIRCLE_IN_RADIANS = (2 * Math::PI)

RADIAN_PER_HOUR = PI / BigDecimal("12")
MINUTES_PER_DEGREE = BigDecimal("60")
MINUTES_PER_HOUR = BigDecimal("60")
SECONDS_PER_MINUTE = BigDecimal("60")
RADIAN_PER_HOUR = Math::PI / 12.0
MINUTES_PER_DEGREE = 60.0
MINUTES_PER_HOUR = 60.0
SECONDS_PER_MINUTE = 60.0
SECONDS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE

FORMATS = %i[dms hms].freeze
Expand All @@ -31,7 +28,7 @@ def from_radians(radians)
end

def from_degrees(degrees)
radians = degrees / PI_IN_DEGREES * PI
radians = degrees / PI_IN_DEGREES * Math::PI
from_radians(radians)
end

Expand Down Expand Up @@ -70,16 +67,12 @@ def atan(ratio)
attr_reader :radians

def initialize(radians)
@radians = if radians.is_a?(Integer) || radians.is_a?(BigDecimal)
BigDecimal(radians)
else
BigDecimal(radians, PRECISION)
end
@radians = radians
freeze
end

def degrees
@radians * PI_IN_DEGREES / PI
@radians * PI_IN_DEGREES / Math::PI
end

def hours
Expand Down Expand Up @@ -153,7 +146,7 @@ def to_dms(deg)
absolute_decimal_minutes - absolute_decimal_minutes.floor
)

Dms.new(sign, degrees, minutes, seconds.to_f.floor(4))
Dms.new(sign, degrees, minutes, seconds.floor(4))
end

def to_hms(hrs)
Expand All @@ -168,7 +161,7 @@ def to_hms(hrs)
absolute_decimal_minutes - absolute_decimal_minutes.floor
)

Hms.new(hours, minutes, seconds.to_f.floor(4))
Hms.new(hours, minutes, seconds.floor(4))
end
end
end
2 changes: 1 addition & 1 deletion lib/astronoby/bodies/sun.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Astronoby
class Sun
SEMI_MAJOR_AXIS_IN_METERS = 149_598_500_000
ANGULAR_DIAMETER = Angle.from_degrees(0.533128)
INTERPOLATION_FACTOR = BigDecimal("24.07")
INTERPOLATION_FACTOR = 24.07

# Source:
# Title: Practical Astronomy with your Calculator or Spreadsheet
Expand Down
2 changes: 1 addition & 1 deletion lib/astronoby/coordinates/equatorial.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def to_horizontal(time:, latitude:, longitude:)
azimuth = Angle.acos(t2)

if ha.sin.positive?
azimuth = Angle.from_degrees(BigDecimal("360") - azimuth.degrees)
azimuth = Angle.from_degrees(360 - azimuth.degrees)
end

Horizontal.new(
Expand Down
2 changes: 1 addition & 1 deletion lib/astronoby/coordinates/horizontal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def to_equatorial(time:)

if @azimuth.sin.positive?
hour_angle_degrees = Angle
.from_degrees(BigDecimal("360") - hour_angle_degrees)
.from_degrees(360 - hour_angle_degrees)
.degrees
end

Expand Down
4 changes: 2 additions & 2 deletions lib/astronoby/geocentric_parallax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class GeocentricParallax
# Chapter: 39 - Calculating correction for parallax

ASTRONOMICAL_UNIT_IN_METERS = 149_597_870_700
EARTH_FLATTENING_CORRECTION = BigDecimal("0.996647")
EARTH_EQUATORIAL_RADIUS = BigDecimal("6378140")
EARTH_FLATTENING_CORRECTION = 0.996647
EARTH_EQUATORIAL_RADIUS = 6378140.0

# Equatorial horizontal parallax
# @param distance [Numeric] Distance of the body from the center of the
Expand Down
14 changes: 7 additions & 7 deletions lib/astronoby/observer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
module Astronoby
class Observer
DEFAULT_ELEVATION = 0
DEFAULT_TEMPERATURE = BigDecimal("283.15")
PRESSURE_AT_SEA_LEVEL = BigDecimal("1013.25")
PASCAL_PER_MILLIBAR = BigDecimal("0.01")
EARTH_GRAVITATIONAL_ACCELERATION = BigDecimal("9.80665")
MOLAR_MASS_OF_AIR = BigDecimal("0.0289644")
UNIVERSAL_GAS_CONSTANT = BigDecimal("8.31432")
DEFAULT_TEMPERATURE = 283.15
PRESSURE_AT_SEA_LEVEL = 1013.25
PASCAL_PER_MILLIBAR = 0.01
EARTH_GRAVITATIONAL_ACCELERATION = 9.80665
MOLAR_MASS_OF_AIR = 0.0289644
UNIVERSAL_GAS_CONSTANT = 8.31432

attr_reader :latitude, :longitude, :elevation, :temperature

Expand Down Expand Up @@ -37,7 +37,7 @@ def initialize(
# Compute an estimation of the atmospheric pressure based on the elevation
# and temperature
#
# @return [BigDecimal] the atmospheric pressure in millibars.
# @return [Float] the atmospheric pressure in millibars.
def pressure
@pressure ||= PRESSURE_AT_SEA_LEVEL * pressure_ratio
end
Expand Down
10 changes: 5 additions & 5 deletions lib/astronoby/time/greenwich_sidereal_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
module Astronoby
class GreenwichSiderealTime
JULIAN_CENTURIES_EXPONENTS = [
BigDecimal("6.697374558"),
BigDecimal("2400.051336"),
BigDecimal("0.000025862")
6.697374558,
2400.051336,
0.000025862
].freeze

attr_reader :date, :time
Expand All @@ -29,7 +29,7 @@ def self.from_utc(utc)
utc.min / 60.0 +
(utc.sec + utc.subsec) / 3600.0

gmst = BigDecimal("1.002737909") * ut_in_hours + t0
gmst = 1.002737909 * ut_in_hours + t0
gmst += 24 if gmst.negative?
gmst -= 24 if gmst > 24

Expand Down Expand Up @@ -61,7 +61,7 @@ def to_utc
a += 24 if a.negative?
a -= 24 if a > 24

utc = BigDecimal("0.9972695663") * a
utc = 0.9972695663 * a

decimal_hour_to_time(date, utc)
end
Expand Down
2 changes: 0 additions & 2 deletions lib/astronoby/util/trigonometry.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require "bigdecimal/math"

module Astronoby
module Util
module Trigonometry
Expand Down
Loading

0 comments on commit 26fb8b4

Please sign in to comment.