File Coverage

lib/Astro/Montenbruck/Ephemeris/Pert.pm
Criterion Covered Total %
statement 56 59 94.9
branch 2 2 100.0
condition 2 2 100.0
subroutine 8 8 100.0
pod 2 2 100.0
total 70 73 95.8


line stmt bran cond sub pod time code
1             package Astro::Montenbruck::Ephemeris::Pert;
2              
3 6     6   34 use strict;
  6         12  
  6         151  
4 6     6   27 use warnings;
  6         12  
  6         150  
5 6     6   64 use Exporter qw/import/;
  6         32  
  6         413  
6             our @EXPORT_OK = qw(pert addthe);
7              
8             our $VERSION = 0.01;
9              
10 6     6   39 use constant OFFSET => 16;
  6         10  
  6         487  
11             use constant {
12 6         3351 OFFSET_M => OFFSET - 1,
13             OFFSET_P => OFFSET + 1,
14 6     6   32 };
  6         26  
15              
16             sub addthe {
17 121598     121598 1 260139 $_[0] * $_[2] - $_[1] * $_[3], $_[1] * $_[2] + $_[0] * $_[3];
18             }
19              
20             sub pert {
21 2938     2938 1 10704 my %arg = @_;
22             my ($callback, $t, $M, $m, $I_min, $I_max, $i_min, $i_max, $phi) =
23 2938         5233 map{ $arg{$_} } qw/callback T M m I_min I_max i_min i_max phi/;
  26442         37205  
24 2938   100     11050 $phi //= 0;
25              
26 2938         4860 my $cos_m = cos( $M );
27 2938         4366 my $sin_m = sin( $M );
28 2938         7029 my @C;
29             my @S;
30 2938         0 my @c;
31 2938         0 my @s;
32              
33 2938         5020 $C[OFFSET] = cos($phi);
34 2938         4216 $S[OFFSET] = sin($phi);
35              
36 2938         5881 for ( my $i = 0; $i < $I_max; $i++ ) {
37 12548         15138 my $j = OFFSET + $i;
38 12548         14085 my $k = $j + 1;
39 12548         17284 ( $C[$k], $S[$k] ) = addthe( $C[$j], $S[$j], $cos_m, $sin_m );
40             }
41 2938         5619 for ( my $i = 0; $i > $I_min; $i-- ) {
42 748         1161 my $j = OFFSET + $i;
43 748         997 my $k = $j - 1;
44 748         1391 ( $C[$k], $S[$k] ) = addthe( $C[$j], $S[$j], $cos_m, -$sin_m );
45             }
46 2938         4231 $c[OFFSET] = 1.0;
47 2938         4963 $c[OFFSET_P] = cos( $m );
48 2938         3647 $c[OFFSET_M] = $c[OFFSET_P];
49 2938         3728 $s[OFFSET] = 0.0;
50 2938         4652 $s[OFFSET_P] = sin( $m );
51 2938         4114 $s[OFFSET_M] = -$s[OFFSET_P];
52 2938         5682 for ( my $i = 1; $i < $i_max; $i++ ) {
53 0         0 my $j = OFFSET + $i;
54 0         0 my $k = $j + 1;
55 0         0 ( $c[$k], $s[$k] ) = addthe( $c[$j], $s[$j], $c[OFFSET_P], $s[OFFSET_P] );
56             }
57 2938         5091 for ( my $i = -1; $i > $i_min; $i-- ) {
58 11632         13720 my $j = OFFSET + $i;
59 11632         13452 my $k = $j - 1;
60 11632         16433 ( $c[$k], $s[$k] ) = addthe( $c[$j], $s[$j], $c[OFFSET_M], $s[OFFSET_M] );
61             }
62              
63 2938         4184 my ($u, $v) = (0, 0);
64              
65             sub {
66 38560     38560   57004 my ( $I, $i, $iT, $dlc, $dls, $drc, $drs, $dbc, $dbs ) = @_;
67 38560         45801 my $k = OFFSET + $I;
68 38560         43174 my $j = OFFSET + $i;
69 38560 100       50787 if ( $iT == 0 ) {
70 36226         50828 ( $u, $v ) = addthe( $C[$k], $S[$k], $c[$j], $s[$j] );
71             }
72             else {
73 2334         2672 $u *= $t;
74 2334         2784 $v *= $t;
75             }
76 38560         77642 $callback->(
77             $dlc * $u + $dls * $v,
78             $drc * $u + $drs * $v,
79             $dbc * $u + $dbs * $v
80             );
81             }
82 2938         25097 }
83              
84             1;
85              
86             __END__
87              
88             =pod
89              
90             =encoding UTF-8
91              
92             =head1 NAME
93              
94             Astro::Montenbruck::Ephemeris::Pert - Calculation of perturbations.
95              
96             =head1 SYNOPSIS
97              
98             use Astro::Montenbruck::Ephemeris::Pert qw /pert/;
99              
100             ($dl, $dr, $db) = (0, 0, 0); # Corrections in longitude ["],
101             $pert_cb = sub { $dl += $_[0]; $dr += $_[1]; $db += $_[2] };
102              
103             $term
104             = pert( T => $t,
105             M => $m1,
106             m => $m3,
107             I_min => 0,
108             I_max => 2,
109             i_min =>-4,
110             i_max =>-1,
111             callback => $pert_cb);
112             $term->(-1, -1,0, -0.2, 1.4, 2.0, 0.6, 0.1, -0.2);
113             $term->( 0, -1,0, 9.4, 8.9, 3.9, -8.3, -0.4, -1.4);
114             ...
115              
116             =head1 DESCRIPTION
117              
118             Calculates perturbations for Sun, Moon and the 8 planets. Used internally by
119             L<Astro::Montenbruck::Ephemeris> module.
120              
121             =head2 EXPORT
122              
123             =over
124              
125             =item * L<pert(%args)>
126              
127             =item * L<addthe($a, $b, $c, $d)>
128              
129             =back
130              
131             =head1 SUBROUTINES/METHODS
132              
133             =head2 pert(%args)
134              
135             Calculates perturbations to ecliptic heliocentric coordinates of the planet.
136              
137             =head3 Named arguments
138              
139             =over
140              
141             =item * B<T> — time in centuries since epoch 2000.0
142              
143             =item *
144              
145             B<M>, B<m>, B<I_min>, B<I_max>, B<i_min>, B<i_max> — internal indices
146              
147             =item *
148              
149             B<callback> — reference to a function which recievs corrections to the 3
150             coordinates and typically applies them (see L</SYNOPSIS>)
151              
152             =back
153              
154             =head2 addthe($a, $b, $c, $d)
155              
156             Calculates C<c=cos(a1+a2)> and C<s=sin(a1+a2)> from the addition theorems for
157             C<c1=cos(a1), s1=sin(a1), c2=cos(a2) and s2=sin(a2)>
158              
159             =head3 Arguments
160              
161             c1, s1, c2, s2
162              
163              
164             =head1 AUTHOR
165              
166             Sergey Krushinsky, C<< <krushi at cpan.org> >>
167              
168             =head1 COPYRIGHT AND LICENSE
169              
170             Copyright (C) 2009-2022 by Sergey Krushinsky
171              
172             This library is free software; you can redistribute it and/or modify
173             it under the same terms as Perl itself.
174              
175             =cut