Building a declination table

[1]:
from kanon.units import Sexagesimal
from kanon.units.precision import set_precision, get_context, TruncatureMode
from kanon.tables import HTable
from kanon.tables.htable import join_multiple
import math

# For these calculations we will round after every operations.

get_context().mutate(tmode=TruncatureMode.ROUND)
[2]:
OBLIQUITY = "23;51,20"
[3]:
# We construct a table of sine from 0 to 90.
x = list(Sexagesimal.range(91))
y = [round(Sexagesimal.from_float(math.sin(math.radians(n)), 3)) for n in x]
sin_table = HTable([x, y], names=("Arg", "Val"), index="Arg")

sin_table
[3]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ; 00,00,00
01 ;00 ; 01,02,50
02 ;00 ; 02,05,38
03 ;00 ; 03,08,25
04 ;00 ; 04,11,07
05 ;00 ; 05,13,46
06 ;00 ; 06,16,18
07 ;00 ; 07,18,44
08 ;00 ; 08,21,01
09 ;00 ; 09,23,10
......
01,21 ;00 ; 59,15,41
01,22 ;00 ; 59,24,58
01,23 ;00 ; 59,33,10
01,24 ;00 ; 59,40,17
01,25 ;00 ; 59,46,18
01,26 ;00 ; 59,51,14
01,27 ;00 ; 59,55,04
01,28 ;00 ; 59,57,48
01,29 ;00 ; 59,59,27
01,30 ;01 ; 00,00,00
[4]:
# We apply a multiplication on all the sine values to get obl_table = Sin(x) * obl

obl = sin_table.get(Sexagesimal(OBLIQUITY))

obl_table = sin_table.apply("Val", lambda x: x * obl)
obl_table

[4]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ; 00,00,00
01 ;00 ; 00,25,25
02 ;00 ; 00,50,49
03 ;00 ; 01,16,12
04 ;00 ; 01,41,33
05 ;00 ; 02,06,54
06 ;00 ; 02,32,11
07 ;00 ; 02,57,26
08 ;00 ; 03,22,37
09 ;00 ; 03,47,46
......
01,21 ;00 ; 23,58,01
01,22 ;00 ; 24,01,46
01,23 ;00 ; 24,05,05
01,24 ;00 ; 24,07,58
01,25 ;00 ; 24,10,24
01,26 ;00 ; 24,12,23
01,27 ;00 ; 24,13,56
01,28 ;00 ; 24,15,03
01,29 ;00 ; 24,15,43
01,30 ;00 ; 24,15,56
[5]:
# Arcsin is sin_table taken from Val to Arg instead of Arg to Val.

arcsin_table = sin_table.copy(set_index="Val")

# For example, if we want arcsin(0.3) :

arcsin_table.get(0.3)

[5]:
17 ; 27,29,50
[6]:
# Finally, we apply arcsin_table.get on every obl_table values to find decl_table = arcsin(obl_table)

decl_table = obl_table.apply("Val", arcsin_table.get)
decl_table
[6]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ;
01 ;00 ; 24,16,14
02 ;00 ; 48,31,31
03 ;01 ; 12,46,15
04 ;01 ; 36,59,26
05 ;02 ; 01,12,38
06 ;02 ; 25,22,23
07 ;02 ; 49,30,13
08 ;03 ; 13,35,19
09 ;03 ; 37,39,20
......
01,21 ;23 ; 32,40,53
01,22 ;23 ; 36,35,12
01,23 ;23 ; 40,02,26
01,24 ;23 ; 43,02,35
01,25 ;23 ; 45,34,38
01,26 ;23 ; 47,38,33
01,27 ;23 ; 49,15,24
01,28 ;23 ; 50,25,10
01,29 ;23 ; 51,06,49
01,30 ;23 ; 51,20,22
[7]:
# Let's make the same calculation with an interpolated sine table.

# First, extract every 12th row until the 60th then every 6th.

sin_table_grid = sin_table[
    [i for i in range(91) if i <= 60 and i % 12 == 0 or i > 60 and i % 6 == 0]
]

sin_table_grid
[7]:
HTable length=11
ArgVal
SexagesimalSexagesimal
00 ;00 ; 00,00,00
12 ;00 ; 12,28,29
24 ;00 ; 24,24,15
36 ;00 ; 35,16,02
48 ;00 ; 44,35,19
01,00 ;00 ; 51,57,41
01,06 ;00 ; 54,48,46
01,12 ;00 ; 57,03,48
01,18 ;00 ; 58,41,20
01,24 ;00 ; 59,40,17
01,30 ;01 ; 00,00,00
[8]:
# We can populate it with its interpolation method (linear by default).

sin_table_pop_linear = sin_table_grid.populate(list(Sexagesimal.range(91)), method="interpolate")

sin_table_pop_linear
[8]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ; 00,00,00
01 ;00 ; 01,02,22
02 ;00 ; 02,04,44
03 ;00 ; 03,07,06
04 ;00 ; 04,09,28
05 ;00 ; 05,11,50
06 ;00 ; 06,14,12
07 ;00 ; 07,16,34
08 ;00 ; 08,18,56
09 ;00 ; 09,21,18
......
01,21 ;00 ; 59,10,50
01,22 ;00 ; 59,20,40
01,23 ;00 ; 59,30,30
01,24 ;00 ; 59,40,17
01,25 ;00 ; 59,43,34
01,26 ;00 ; 59,46,51
01,27 ;00 ; 59,50,08
01,28 ;00 ; 59,53,25
01,29 ;00 ; 59,56,42
01,30 ;01 ; 00,00,00
[9]:
# You can use other types of interpolation, for example a quadratic interpolation.

from kanon.tables.interpolations import quadratic_interpolation

sin_table_grid.interpolate = quadratic_interpolation

# This interpolation method needs a higher precision to avoid weird results.
with set_precision(pmode=5):
    sin_table_pop_quadratic = sin_table_grid.populate(list(Sexagesimal.range(91)), method="interpolate")

sin_table_pop_quadratic
[9]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ; 00,00,00,00,00
01 ;00 ; 01,03,37,23,33
02 ;00 ; 02,07,01,09,12
03 ;00 ; 03,10,11,16,57
04 ;00 ; 04,13,07,46,48
05 ;00 ; 05,15,50,38,45
06 ;00 ; 06,18,19,52,48
07 ;00 ; 07,20,35,28,57
08 ;00 ; 08,22,37,27,12
09 ;00 ; 09,24,25,47,33
......
01,21 ;00 ; 59,15,37,52,30
01,22 ;00 ; 59,24,55,13,20
01,23 ;00 ; 59,33,08,15,50
01,24 ;00 ; 59,40,17,00,00
01,25 ;00 ; 59,46,17,38,20
01,26 ;00 ; 59,51,12,53,20
01,27 ;00 ; 59,55,02,45,00
01,28 ;00 ; 59,57,47,13,20
01,29 ;00 ; 59,59,26,18,20
01,30 ;01 ; 00,00,00,00,00
[10]:
# Another type of interpolation can come from filling a interpolation grid made from populate
# With this you can use methods interpolating the whole table at once, like euclidean distribution interpolations

sin_table_pop_euclidean = sin_table_grid.populate(list(Sexagesimal.range(91)))
sin_table_pop_euclidean = sin_table_pop_euclidean.fill("distributed_convex")

sin_table_pop_euclidean
[10]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ; 00,00,00
01 ;00 ; 01,02,22
02 ;00 ; 02,04,44
03 ;00 ; 03,07,06
04 ;00 ; 04,09,28
05 ;00 ; 05,11,50
06 ;00 ; 06,14,12
07 ;00 ; 07,16,34
08 ;00 ; 08,18,57
09 ;00 ; 09,21,20
......
01,21 ;00 ; 59,10,47
01,22 ;00 ; 59,20,37
01,23 ;00 ; 59,30,27
01,24 ;00 ; 59,40,17
01,25 ;00 ; 59,43,34
01,26 ;00 ; 59,46,51
01,27 ;00 ; 59,50,08
01,28 ;00 ; 59,53,25
01,29 ;00 ; 59,56,42
01,30 ;01 ; 00,00,00
[11]:
# Comparing the 2nd difference between the true sine table and the interpolated ones.

true_2diff = sin_table.diff(n=2, new_name="True Sine 2-diff")
interpolated_linear_2diff = sin_table_pop_linear.diff(n=2, new_name="Linear Sine 2-diff")
interpolated_quadratic_2diff = sin_table_pop_quadratic.diff(n=2, new_name="Quadratic Sine 2-diff")
interpolated_euclidean_2diff = sin_table_pop_euclidean.diff(n=2, new_name="Distributed Sine 2-diff")

# Now we have 4 tables with the same arguments. We can compare them side to side by joining them.

join_multiple(true_2diff, interpolated_linear_2diff, interpolated_quadratic_2diff, interpolated_euclidean_2diff)
[11]:
HTable length=91
ArgTrue Sine 2-diffLinear Sine 2-diffQuadratic Sine 2-diffDistributed Sine 2-diff
SexagesimalSexagesimalSexagesimalSexagesimalSexagesimal
00 ;00 ; 00,00,0000 ; 00,00,0000 ; 00,00,00,00,0000 ; 00,00,00
01 ;00 ; 01,02,5000 ; 01,02,2200 ; 01,03,37,23,3300 ; 01,02,22
02 ;-00 ; 00,00,0200 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
03 ;-00 ; 00,00,0100 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
04 ;-00 ; 00,00,0500 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
05 ;-00 ; 00,00,0300 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
06 ;-00 ; 00,00,0700 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
07 ;-00 ; 00,00,0600 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
08 ;-00 ; 00,00,0900 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,01
09 ;-00 ; 00,00,0800 ; 00,00,00-00 ; 00,00,13,37,5400 ; 00,00,00
...............
01,21 ;-00 ; 00,01,0400 ; 00,00,00-00 ; 00,01,04,18,2000 ; 00,00,00
01,22 ;-00 ; 00,01,0600 ; 00,00,00-00 ; 00,01,04,18,2000 ; 00,00,01
01,23 ;-00 ; 00,01,0500 ; 00,00,00-00 ; 00,01,04,18,2000 ; 00,00,00
01,24 ;-00 ; 00,01,05-00 ; 00,00,03-00 ; 00,01,04,18,2000 ; 00,00,00
01,25 ;-00 ; 00,01,06-00 ; 00,06,30-00 ; 00,01,08,05,50-00 ; 00,06,33
01,26 ;-00 ; 00,01,0500 ; 00,00,00-00 ; 00,01,05,23,2000 ; 00,00,00
01,27 ;-00 ; 00,01,0600 ; 00,00,00-00 ; 00,01,05,23,2000 ; 00,00,00
01,28 ;-00 ; 00,01,0600 ; 00,00,00-00 ; 00,01,05,23,2000 ; 00,00,00
01,29 ;-00 ; 00,01,0500 ; 00,00,00-00 ; 00,01,05,23,2000 ; 00,00,00
01,30 ;-00 ; 00,01,0600 ; 00,00,01-00 ; 00,01,05,23,2000 ; 00,00,01
[12]:
# With this newly built table we are able to construct a new declination table.

obl_linear = sin_table_pop_linear.get(Sexagesimal(OBLIQUITY))

obl_table_linear = sin_table_pop_linear.apply("Val", lambda x: x * obl)
arcsin_table_linear = sin_table_pop_linear.copy(set_index="Val")

obl_table_linear.apply("Val", arcsin_table_linear.get)
[12]:
HTable length=91
ArgVal
SexagesimalSexagesimal
00 ;00 ;
01 ;00 ; 24,15,35
02 ;00 ; 48,32,08
03 ;01 ; 12,47,43
04 ;01 ; 37,03,18
05 ;02 ; 01,19,51
06 ;02 ; 25,35,26
07 ;02 ; 49,51,59
08 ;03 ; 14,07,34
09 ;03 ; 38,23,09
......
01,21 ;23 ; 31,37,07
01,22 ;23 ; 35,37,39
01,23 ;23 ; 39,37,11
01,24 ;23 ; 43,36,43
01,25 ;23 ; 44,56,14
01,26 ;23 ; 46,16,44
01,27 ;23 ; 47,37,15
01,28 ;23 ; 48,56,46
01,29 ;23 ; 50,17,17
01,30 ;23 ; 51,37,47