An improved C++ Poisson series processor with its applications
Abstract
One of major problems in celestial mechanics is the management of the long developments in Fourier or Poisson series used to describe the perturbed motion in the planetary system. In this work we will develop a software package suitable for managing these objects. This package includes the ordinary arithmetic operations with Poisson series—such as sum or product—as well as the most commonly used functions , , or , among others. Derivation or integration procedures with respect to time of these objects have been implemented and inversion or serialization procedures are also attainable to obtain such series. All the programming has been accomplished overloading the arithmetic and functional operators natural to C++ with the intention of allowing the programmer to work in a more friendly way and treating the series as if they were mere numbers. In this work we extend the processor in order to obtain the solution to perturbed problems which solution is in the form of a Poisson series. These algorithms have been written in C++.
1 INTRODUCTION
One of the main goals of celestial mechanics is to study the planetary motion in the solar system, that is, the construction of planetary theories. Planetary theories can be classified as analytical, semianalytical, and numerical. The analytical theories are based on the literal development of the perturbation function.1-3 The semianalytical theories are based on developments of the perturbative potential using numerical values for the coefficients of Fourier series and literal expressions for the arguments of the trigonometric functions.4, 5 Numerical theories can be obtained by numerical integration of the motion equations. To this purpose it may be advisable to consult.6
To construct analytical and semianalytical theories it is necessary to obtain the developments of the main magnitudes of the two-body problem as Fourier series of the anomalies. To this purpose see References 2, 3, 7 if the mean anomalies are used and for other anomalies.8-12
The terms of this series are the so-called Poisson terms and the complete series is known as a Poisson series. To integrate the Lagrange planetary equations it is necessary to work with these objects. The management of these series is quite difficult and it is convenient to have a Poisson series processor in order to manipulate these objects in a natural form.
A Poisson series processor is a software package containing a set of special functions programmed to deal with Poisson series. The first Poisson series processor was developed by Broucke13 and it was coded in Fortran language. Other Poisson series processors—designed for specific purposes—were developed by Ivanova,14 Abad,15 and Navarro.16 In the next section a new special software package to improve the handling of series of Poisson in the perturbative methods.
To construct a Poisson series processor it is necessary to define a previous C++ class called tPoisson, which members are the double precision numbers A, B, defining the amplitude and the phase of the Poisson term; the integer i, that represents the time exponent; and n1, … , nN, which symbolizes the angular coefficients of the mean anomalies of the Poisson term.
This class contains methods to set and get the values of the members and methods, such as ==, >=, or !=, declared to compare two Poisson terms following specific criteria. The methods have been implemented using the operator overloading technique in order to get a comfortable usage for the final user.
Based on the previous concepts and on the native C++ vector class, a new class—named sPoisson—has been developed. The members of this new class are vectors of terms of Poisson. This class contains the methods of the class vector and a set of private methods to sort, compact, or arrange Poisson series.
The main public methods included in poisson.h are the arithmetic operations +, −, ∗, pow; the extension of the most common functions , , to be evaluated over Poisson series;17 and functional operations such as Taylor developments and series inversion procedures based on Lagrange and Deprit methods.18 The operators and common functions have been overloaded in order to be more user friendly.
- If at least one kj coefficient is not zero, the first not zero coefficient will be positive, A will be positive, and . If all kj are zero, then A will be replaced by and B will be set to zero.
- In a Poisson series only one term with the same coefficients k1, … , kp and the same powers of the spatial variables can be held. If recurrence occurs, the processor will merge the similar terms in the appropriate way.
In this work a processor dealing with vectors of Poisson series has been built. A Poisson series vector, vPoisson sp[N + 1]—with N fixed in advance is an object where sp[0], sp[1], … , sp[N] respectively represent the terms of order 0, 1, … , N in ε of the solution of a perturbed problem, which its solution can be developed as a power series of ε. This processor evaluate in an automatic form the development of the second members of perturbed equation, thus avoiding having to develop in Taylor series in manual mode, which is generally very tedious.
In Section 1 we will introduce the problem by defining the Poisson series and its usage problems; this section contains the general background of the problem.
In Section 2, the Poisson series processor is extended in order to manage these objects as vectors sp[N + 1] containing sp[k] k = 0, … , N a Poisson series containing the terms of order k in a parameter ε. This section encloses a subsection explaining the content of the main classes of the taylor_poisson.h package. In Section 3, a set of simple numerical examples are developed in order to show the performance of the new processor. In Section 4, the main conclusions of this work are exposed.
2 THE TAYLOR PROCESSOR SERIES
In these paragraphs we introduce the problems depending on one or more small paramaters ε1, … , εk, which orders are o1, … , ok. In this article we will only focus on one-parameter problems, as its explanation is simpler and the generalization to more parameters can be easily accomplished by taking the greater as ε and the rest as . The method used in perturbation theory to solve the problem consists of the preliminary integration of the differential equations for ε = 0. We obtain a solution , where is a set of constants equaling the number of variables which values are determined by the initial conditions of the system.
A commonly used technique to solve the whole problem (ε ≠ 0) is the method known as variation of constants, which swaps the constants A1, … , An with the functions A1(t), … , An(t). Thus, the substitution of these functions in satisfies the complete equation. The method of variation of constants in many problems leads to linear differential equations of the form , where F is a matrix, which elements have the same order as ε. Generally, the method used to solve this system is the method of successive iterations. Starting with the values of that appear in the unperturbed problem we obtain a solution of first order in ε. Coming out of this solution, , we develop in second order in and we obtain and the process goes on successively.
In many problems, such as planetary theories, mathematical perturbed pendulums or with large oscillations, the quantities adopt the form of a Poisson series, so, we are aimed to extend our processor in order to be able to automatically calculate the values of , , and so on up to order N, established in advance.
With these operations it is possible to manipulate Poisson series of the form , represented as vectors (sp[0], sp[1], … , sp[i]), in a way that allows to redefine all the operations and functions, such as , , , , (1 + sp)r, and so on, included in the Poisson series processor posison_vector.h. Functions and operators can also be overloaded and this allows to create another C++ class, namely taylor_poisson.h. This new class empowers a more friendly and natural utilization of the equations linked to the method of variation of constants in the perturbed problem. Besides, the writing of the code dealing with that problem in different orders of perturbation can be accomplish more easily. This prevents the programmer from manually developing the Taylor series of the right-hand side of the equations, which in cases such as the Lagrange equations can be extraordinarily tedious.
The Poisson series processor on which the one presented here is based has been extensively tested, as a sample in the case of an analytical planetary theory.19 The kernel of the class vPoisson is schematically shown as follows.
2.1 Classes tPoisson and sPoisson
First, we lightly describe the classes previously built: tPoisson, a Poisson term; and sPoisson, a Poisson series. We will then define the new class vPoisson, a vector Poisson series, based on the mentioned classes before.
Class tPoisson
This class will be the fundamental tool to be able to create, manipulate and, ultimately, operate Poisson terms and construct Poisson series as a vector of Poisson terms.
- m_A. A double precision value to store the variable A.
- m_B. A double precision value to store the variable B.
- m_i. A whole value to store the exponent i.
- m_j. A static vector of whole values to store the NP variables n1, … , nk.
- tPoisson(). A constructor to create an instance of Poisson term with all its values set to zero.
- tPoisson (const tPoisson&). A copy constructor to create a Poisson term; the new term is copied from a given one.
- tPoisson (double, int, int[], double). A constructor to create a Poisson term explicitly specifying all its members.
- tPoisson (double). A constructor to create a Poisson term by defining solely the member m_A and nullifying the rest. This method will let us create a Poisson term associated to a real number.
- tPoisson(). An instance destructor to delete Poisson terms and free the memory consumed.
- double getA(). Method to access and read the value of the member m_A.
- void setA(const double&). Method to allocate a value to the member m_A in a term.
- double getB(). Method to retrieve the value of member m_B.
- void setB(const double&). Method to allocate a value to the member m_B of a term.
- int getI(). Method to retrieve the value of member m_I.
- void setI(const int&). Method to allocate a value to the member m_I of a term.
- int getJ(int). This method retrieves the value of the angular variable of a term given its position in the vector.
- void setJ(int, int). Method to allocate the value of an angular variable given its position in the vector.
- bool operator== (const tPoisson&, const tPoisson&). This function overloads the == operator in order to be able to compare two Poisson terms. For the proper functioning of the processor it is important to highlight that two Poisson terms are considered equal if both their members, m_I, and their vectors, m_J, coincide.
- bool operator!= (const tPoisson&, const tPoisson&). Overloads the != operator in order to be able to determine if two Poisson terms are different. Two terms are different if there are unequal. The definition of the function for this operator has been constructed based on the negation of the equality operator.
- bool operator> (const tPoisson&, const tPoisson&). Overloads the > operator allowing to decide, under certain criteria, if a Poisson term is greater than another.
- bool operator>= (const tPoisson&, const tPoisson&). Both the definitions of the overloaded functions > and == have been defined; the operator >= combines both of them.
- bool operator< (const tPoisson&, const tPoisson&). Overloads the < operator allowing to decide, under certain criteria, if a Poisson term is less than another.
- bool operator<= (const tPoisson&, const tPoisson&). The <= operator is a combination of the functions < and == and both operators have been previously implemented.
Class sPoisson
Members:
The members of the class sPoisson are the same ones as the C++ standard library container vector, since it has been defined as #sPoisson vector<tPoisson>.
Methods:
The methods of this class are the methods corresponding to the vector class and the ones inherited from the tPoisson class. Moreover, some operators have been overloaded and some functions have also been programmed.
- sPoisson& operator*(sPoisson&, sPoisson&). This operator has been devised to multiply two Poisson series.
- sPoisson& operator*(const sPoisson&, double). This operator right-multiplies a Poisson series by a real number.
- sPoisson& operator*(double, const sPoisson&). In the case, this operator left-multiplies a Poisson series by a real number.
- sPoisson& operator/ (const sPoisson &, double). Operator to divide a Poisson series by a real number.
- sPoisson& operator+(const sPoisson&, const sPoisson&). Operator to perform the addition of two Poisson series.
- sPoisson& operator+(const sPoisson&, double). Operator to right-add a Poisson series and a real number.
- sPoisson& operator+(double, const sPoisson&). Operator to left-add a Poisson series with a real number.
- sPoisson& operator-(const sPoisson&, const sPoisson&). Operator to subtract a Poisson series from another.
Other functions:
- sPoisson& pow(sPoisson&, int). This function has two parameters: a Poisson series and whole number representing the exponent. Based upon the operator “*,” this function implements the power of a Poisson series by multiplying the series by itself as many times as the value indicated by the exponent. It returns the compacted Poisson series after all the operations have been performed.
- sPoisson& exp(sPoisson&). This function admits a Poisson series as a parameter. According to the established precision, it computes an exponential approximation based on Taylor's formula and returns a new compacted Poisson series.
- sPoisson& sin(sPoisson&). This function admits a Poisson series as a parameter. According to the established precision, it computes an approximation of the function sine based on the Taylor's formula and returns a new compacted Poisson series.
- sPoisson& cos(sPoisson&). This function admits a Poisson series as a parameter. According to the established precision, it computes an approximation of the function cosine based on the Taylor's formula and returns a new compacted Poisson series.
- sPoisson& sqrt(sPoisson& sp, double). This function admits two parameters: a Poisson series and the index of the root. According to the established precision, it computes an approximation of the function based on the Taylor's formula and returns a new compacted Poisson series.
- sPoisson& log(sPoisson&). This function admits a Poisson series as a parameter. According to the established precision, it computes an approximation of the function based on the Taylor's formula and returns a new compacted Poisson series.
- void arregla(sPoisson&). This function alters the content of a Poisson series in order to meet the convenient characteristics for its future treatment. If all the angular variables (m_j) are zero and m_B is not, it is advisable to make cos(m_B) part of m_A. Besides, it is also desirable to reduce the angles to the interval [0, 2[.
- sPoisson& trunca(const sPoisson&, double). This function accepts a Poisson series and a positive number representing the maximum error as parameters. It returns another Poisson series where the terms with a smaller amplitude than the maximum error have been deleted.
- sPoisson& compacta(const sPoisson&). It accepts a Poisson series as a parameter and computes another series where its terms have been arranged, operated, unified and simplified (equality holds depending on the overloaded operator == defined in the class tPoisson).
2.2 Class vPoisson
Based on the previous classes—tPoisson and sPoisson—and their basic operations defined in (5), (6), and (7) we can build the vPoisson class. This new class is the core that will allow the construction of the Taylor series processor.
Members:
The members of this class are the members of the vector class included in the C++ standard library, as the class has been implemented by means of #vPoisson vector<sPoisson>.
- vPoisson& operator+(const vPoisson&, const vPoisson&). This operator admits two vectors of Poisson series as parameters. It computes the addition of both vectors and returns the result as another vector.
- vPoisson& operator*(const vPoisson&, const vPoisson&). This operator admits two vectors of Poisson series as parameters. It computes the product of both series. Especially in this operator it is important to highlight that the order in the series is always held, as terms of the same order must be kept together.
- vPoisson& pow(const vPoisson&, int). This function admits two parameters: a vector and an positive integer. It multiplies the vector as times as the integer indicates, but always maintaining the terms of the same order in its adequate position within the series in the vector.
- vPoisson& sin(const vPoisson&). This function admits a Poisson series vector as a parameter. According to the established precision, it computes an approximation of the sine function based on the Taylor's formula and returns a vector of series. Within this new vector the terms of the same order are kept together as part of the same Poisson series.
- vPoisson& cos(const vPoisson&). This function admits a Poisson series vector as a parameter. According to the established precision, it computes an approximation of the cosine function based on the Taylor's formula and returns a vector of series. Within this new vector the terms of the same order are kept together as part of the same Poisson series.
- vPoisson& exp(const vPoisson&). This function admits a Poisson series vector as a parameter. According to the established precision, it computes an approximation of the exponential function based on the Taylor's formula and returns a vector of series. Within this new vector the terms of the same order are kept together as part of the same Poisson series.
- vPoisson& log(const vPoisson&). This function admits a Poisson series vector as a parameter. According to the established precision, it computes an approximation of the function based on the Taylor's formula and returns a vector of series. Within this new vector the terms of the same order are kept together as part of the same Poisson series.
- vPoisson& compacta(vPoisson&). This function admits a Poisson series vector as a parameter. As the vector comprises a list of several Poisson series, it individually manipulates each one by applying the function compacta, previously defined within the class sPoisson.
By way of example, next section includes several problems in order to prove the efficiency of the package.
The kernel including the classes introduced before can be found in the URL http://mecanicaceleste.uji.es.
3 NUMERICAL EXAMPLE
Notice that and so .
In order to simplify the calculations, temporal units have been chosen conducive to have for the linear approximation, and so, .
If the amplitude is not small, the model of harmonic oscillator cannot be applied to mathematical pendulum. For example, for A = 0.9, we have that the period of linear oscillator is and the real period is Tr = 6.61687.
The Duffing oscillator improves the solution given by linear oscillator; however, if the initial amplitudes are large, the periods do not converge to the true period of the mathematical pendulum.
A classic solution using the perturbation method is as follows: to solve this system we apply a successive iterative technique. First, we will obtain the terms A(t) and B(t) as a first-order approximation in ε; these results are provided by the Poisson series processor. Then, after integrating and considering the initial conditions we obtain the terms up to third order of perturbation. They are shown below.
In order to show the iterations of this problem—and considering that t is the only angular variable—the terms will be presented as in favor of greater clarity.
Another point worth underlining is the presence of a term in the form , which is a nonperiodic term—in fact t derives from the Taylor approximations of periodic terms—and the approximation is only valid for not too large values of t. As the movement is periodic and symmetric with respect to x = 0, it is enough to calculate the solution up to and extend it by periodicity and symmetry.
The period in this final case results T3 = 6.38137 and it remains unchanged in a fourth-order perturbation.
The periods are computed by solving the equation xi(t) = 0 around the point and considering the root , we have which slightly differs from the real one—the one provided by elliptic functions—in less than 4 · 10−6 in the interval [0, T3/4].
This problem is solved by using the perturbation theory arranging an appropriate precision for one-fourth of the period, and from this solution we can extend them for other time.
To sum up, the example in this section demonstrates the precision of the method. The solution of the mathematical pendulum with initial conditions x(0) = 0.5, is obtained and the periods for each order of perturbation are shown.
4 CONCLUDING REMARKS
The usage of Poisson series is of utmost importance in the performance of perturbative methods in celestial mechanics. In this article the processor included in the class poisson.h has been extended. This extension has been successfully tested in problems as complex as the development of first-order planetary theories. Using the processor in higher-order theories involves the development of the second members of the Lagrange planetary equations as Taylor series, which is a burdensome process.
The taylor_poisson.h processor deals with vPoisson objects defined as Poisson series vectors. The components of these vectors correspond to the order of the small parameter around which the perturbative method is employed. The potential advantage of this processor is that the manual development in Taylor series of the small parameter ε is not required, as the processor has been programmed to do all the work automatically.
The efficiency of the processor has been tested in a simple example involving a mathematical pendulum with nonsmall oscillations, where linear modeling is not appropriate. On the one hand, a clean illustrative example has been chosen because the prime objective is to focus on the simplicity of usage of the processor when dealing with different perturbative orders; on the other hand, we want to compare the results with the ones produced by Mathematica, which is a unviable task when dealing with problems involving planetary theories.
- • The Poisson series processor is suitable for the ordinary requirements of celestial mechanics.
- • The Poisson series vector processor is appropriate to study, by the method of variation of parameters, problems close to problems admitting periodic solutions.
- • The exemplification of the solution for the oscillations of a mathematical pendulum using a perturbative method when the amplitude is small can be handily automated with a Poisson series vector processor.
- • The results obtained with the processor—which kernel is included in the class taylor_poisson.h—have been compared with the ones achieved with Mathematica and they are exactly the same.
- • The method followed is extensible to more complicated problems, such as the analytical theory of an artificial satellite, planetary theories, and other problems linked with celestial mechanics.
- • The kernel of the processor is included in the C++ class taylor_poisson.h and can be accessed under General Public License v3 at the URL http://mecanicaceleste.uji.es.
ACKNOWLEDGMENTS
This information is not included in this version in order to do not show information about the authors.
CONFLICT OF INTEREST
The authors declare that they have no conflict of interest with regard to this work.
APPENDIX: C++ CODE
This appendix contains the C++ code used to compute the solution of the problem (31) with initial conditions x(0) = 0.5, up to third order of perturbation. To start the solution of the unperturbed problem has been used.
Biographies
José Antonio López Ortí Academic background: (1) Master in Mathematics science (1982). (2) Doctor in Mathematics (1987). He was Assistant since 1983 to 1984, Lecturer since 1984 from 1989, Professor (associated) since 1989, and Full Professor since 2011 to now. https://www.uji.es/departaments/mat/base/estructura/personal/?urlRedirect=https://www.uji.es/departaments/mat/base/estructura/personal/&url=/departaments/mat/base/estructura/personal&p_departamento=92&p_profesor=65082; https://www.researchgate.net/profile/Jose_Lopez_Orti
Vicente Agost Gómez—born in 1974 in Castellón, Spain—graduated in Computer Engineering in 1997 and in specific Computational Mathematics in 2008 at Jaume I. He holds a master degree in Computational Mathematics and earned a Ph.D. in Sciences at Jaume I university in 2020. He obtained his permanent position as a secondary school mathematics teacher in 2008 and joined Jaume I university as a part-time associate professor in the same year. He is presently conducting research into celestial mechanics and specifically into orbital motion.
Miguel Barreda Rochera was born in Castelló, Spain, in 1963. He went to primary school at the school Colegio Nacional de Prácticas Aneja in Castelló and to secondary school at the high school Francisco Ribalta in Castelló. He studies Mathematics at the University of Valéncia and received the Doctor degree in Mathematical Sciences from the University of Valéncia in 1994. From 1988 to 1990 he was Research Fellow at the Collegi Universitari de Castelló (University of Valéncia), Assistant Professor at University of Valéncia in 1991 and, since 1991 he is Associate Professor at the University Jaume I of Castelló. The focus of Dr. Barreda Rochera's research has been the study of rigid motions in General Relativity and Celestial Mechanics. ORCID: https://orcid.org/0000-0001-6876-5411