123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- [/
- Copyright (c) 2006 Xiaogang Zhang
- Copyright (c) 2006 John Maddock
- Use, modification and distribution are subject to the
- Boost Software License, Version 1.0. (See accompanying file
- LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ]
- [section:ellint_1 Elliptic Integrals of the First Kind - Legendre Form]
- [heading Synopsis]
- ``
- #include <boost/math/special_functions/ellint_1.hpp>
- ``
- namespace boost { namespace math {
- template <class T1, class T2>
- ``__sf_result`` ellint_1(T1 k, T2 phi);
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_1(T1 k, T2 phi, const ``__Policy``&);
- template <class T>
- ``__sf_result`` ellint_1(T k);
- template <class T, class ``__Policy``>
- ``__sf_result`` ellint_1(T k, const ``__Policy``&);
- }} // namespaces
-
- [heading Description]
- These two functions evaluate the incomplete elliptic integral of the first kind
- ['F([phi], k)] and its complete counterpart ['K(k) = F([pi]/2, k)].
- [graph ellint_1]
- The return type of these functions is computed using the __arg_promotion_rules
- when T1 and T2 are different types: when they are the same type then the result
- is the same type as the arguments.
- template <class T1, class T2>
- ``__sf_result`` ellint_1(T1 k, T2 phi);
-
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_1(T1 k, T2 phi, const ``__Policy``&);
-
- Returns the incomplete elliptic integral of the first kind ['F([phi], k)]:
- [equation ellint2]
- Requires k[super 2]sin[super 2](phi) < 1, otherwise returns the result of __domain_error.
- [optional_policy]
- template <class T>
- ``__sf_result`` ellint_1(T k);
-
- template <class T>
- ``__sf_result`` ellint_1(T k, const ``__Policy``&);
-
- Returns the complete elliptic integral of the first kind ['K(k)]:
- [equation ellint6]
- Requires |k| < 1, otherwise returns the result of __domain_error.
- [optional_policy]
- [heading Accuracy]
- These functions are computed using only basic arithmetic operations, so
- there isn't much variation in accuracy over differing platforms.
- Note that only results for the widest floating point type on the
- system are given as narrower types have __zero_error. All values
- are relative errors in units of epsilon.
- [table_ellint_1]
- The following error plot are based on an exhaustive search of the functions domain, MSVC-15.5 at `double` precision,
- and GCC-7.1/Ubuntu for `long double` and `__float128`.
- [graph elliptic_integral_k__double]
- [graph elliptic_integral_k__80_bit_long_double]
- [graph elliptic_integral_k____float128]
- [heading Testing]
- The tests use a mixture of spot test values calculated using the online
- calculator at [@http://functions.wolfram.com/ functions.wolfram.com],
- and random test data generated using
- NTL::RR at 1000-bit precision and this implementation.
- [heading Implementation]
- These functions are implemented in terms of Carlson's integrals using the relations:
- [equation ellint19]
- and
- [equation ellint20]
- [endsect] [/section:ellint_1 Elliptic Integrals of the First Kind - Legendre Form]
- [section:ellint_2 Elliptic Integrals of the Second Kind - Legendre Form]
- [heading Synopsis]
- ``
- #include <boost/math/special_functions/ellint_2.hpp>
- ``
- namespace boost { namespace math {
- template <class T1, class T2>
- ``__sf_result`` ellint_2(T1 k, T2 phi);
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_2(T1 k, T2 phi, const ``__Policy``&);
- template <class T>
- ``__sf_result`` ellint_2(T k);
- template <class T, class ``__Policy``>
- ``__sf_result`` ellint_2(T k, const ``__Policy``&);
- }} // namespaces
-
- [heading Description]
- These two functions evaluate the incomplete elliptic integral of the second kind
- ['E([phi], k)] and its complete counterpart ['E(k) = E([pi]/2, k)].
- [graph ellint_2]
- The return type of these functions is computed using the __arg_promotion_rules
- when T1 and T2 are different types: when they are the same type then the result
- is the same type as the arguments.
- template <class T1, class T2>
- ``__sf_result`` ellint_2(T1 k, T2 phi);
-
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_2(T1 k, T2 phi, const ``__Policy``&);
-
- Returns the incomplete elliptic integral of the second kind ['E([phi], k)]:
- [equation ellint3]
- Requires k[super 2]sin[super 2](phi) < 1, otherwise returns the result of __domain_error.
- [optional_policy]
- template <class T>
- ``__sf_result`` ellint_2(T k);
-
- template <class T>
- ``__sf_result`` ellint_2(T k, const ``__Policy``&);
-
- Returns the complete elliptic integral of the second kind ['E(k)]:
- [equation ellint7]
- Requires |k| < 1, otherwise returns the result of __domain_error.
- [optional_policy]
- [heading Accuracy]
- These functions are computed using only basic arithmetic operations, so
- there isn't much variation in accuracy over differing platforms.
- Note that only results for the widest floating point type on the
- system are given as narrower types have __zero_error. All values
- are relative errors in units of epsilon.
- [table_ellint_2]
- The following error plot are based on an exhaustive search of the functions domain, MSVC-15.5 at `double` precision,
- and GCC-7.1/Ubuntu for `long double` and `__float128`.
- [graph elliptic_integral_e__double]
- [graph elliptic_integral_e__80_bit_long_double]
- [graph elliptic_integral_e____float128]
- [heading Testing]
- The tests use a mixture of spot test values calculated using the online
- calculator at [@http://functions.wolfram.com
- functions.wolfram.com], and random test data generated using
- NTL::RR at 1000-bit precision and this implementation.
- [heading Implementation]
- These functions are implemented in terms of Carlson's integrals
- using the relations:
- [equation ellint21]
- and
- [equation ellint22]
- [endsect] [/section:ellint_2 Elliptic Integrals of the Second Kind - Legendre Form]
- [section:ellint_3 Elliptic Integrals of the Third Kind - Legendre Form]
- [heading Synopsis]
- ``
- #include <boost/math/special_functions/ellint_3.hpp>
- ``
- namespace boost { namespace math {
- template <class T1, class T2, class T3>
- ``__sf_result`` ellint_3(T1 k, T2 n, T3 phi);
- template <class T1, class T2, class T3, class ``__Policy``>
- ``__sf_result`` ellint_3(T1 k, T2 n, T3 phi, const ``__Policy``&);
- template <class T1, class T2>
- ``__sf_result`` ellint_3(T1 k, T2 n);
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_3(T1 k, T2 n, const ``__Policy``&);
- }} // namespaces
-
- [heading Description]
- These two functions evaluate the incomplete elliptic integral of the third kind
- ['[Pi](n, [phi], k)] and its complete counterpart ['[Pi](n, k) = E(n, [pi]/2, k)].
- [graph ellint_3]
- The return type of these functions is computed using the __arg_promotion_rules
- when the arguments are of different types: when they are the same type then the result
- is the same type as the arguments.
- template <class T1, class T2, class T3>
- ``__sf_result`` ellint_3(T1 k, T2 n, T3 phi);
-
- template <class T1, class T2, class T3, class ``__Policy``>
- ``__sf_result`` ellint_3(T1 k, T2 n, T3 phi, const ``__Policy``&);
-
- Returns the incomplete elliptic integral of the third kind ['[Pi](n, [phi], k)]:
- [equation ellint4]
- Requires ['k[super 2]sin[super 2](phi) < 1] and ['n < 1/sin[super 2]([phi])], otherwise
- returns the result of __domain_error (outside this range the result
- would be complex).
- [optional_policy]
- template <class T1, class T2>
- ``__sf_result`` ellint_3(T1 k, T2 n);
-
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_3(T1 k, T2 n, const ``__Policy``&);
-
- Returns the complete elliptic integral of the first kind ['[Pi](n, k)]:
- [equation ellint8]
- Requires ['|k| < 1] and ['n < 1], otherwise returns the
- result of __domain_error (outside this range the result would be complex).
- [optional_policy]
- [heading Accuracy]
- These functions are computed using only basic arithmetic operations, so
- there isn't much variation in accuracy over differing platforms.
- Note that only results for the widest floating point type on the
- system are given as narrower types have __zero_error. All values
- are relative errors in units of epsilon.
- [table_ellint_3]
- [heading Testing]
- The tests use a mixture of spot test values calculated using the online
- calculator at [@http://functions.wolfram.com
- functions.wolfram.com], and random test data generated using
- NTL::RR at 1000-bit precision and this implementation.
- [heading Implementation]
- The implementation for [Pi](n, [phi], k) first siphons off the special cases:
- [expression ['[Pi](0, [phi], k) = F([phi], k)]]
- [expression ['[Pi](n, [pi]/2, k) = [Pi](n, k)]]
- and
- [equation ellint23]
- Then if n < 0 the relations (A&S 17.7.15/16):
- [equation ellint24]
- are used to shift /n/ to the range \[0, 1\].
- Then the relations:
- [expression ['[Pi](n, -[phi], k) = -[Pi](n, [phi], k)]]
- [expression ['[Pi](n, [phi]+m[pi], k) = [Pi](n, [phi], k) + 2m[Pi](n, k) ; n <= 1]]
- [expression ['[Pi](n, [phi]+m[pi], k) = [Pi](n, [phi], k) ; n > 1] [indent] [indent]
- [footnote I haven't been able to find a literature reference for this
- relation, but it appears to be the convention used by Mathematica.
- Intuitively the first ['2 * m * [Pi](n, k)] terms cancel out as the
- derivative alternates between +[infin] and -[infin].]]
- are used to move [phi] to the range \[0, [pi]\/2\].
- The functions are then implemented in terms of Carlson's integrals using the relations:
- [equation ellint25]
- and
- [equation ellint26]
- [endsect] [/section:ellint_3 Elliptic Integrals of the Third Kind - Legendre Form]
- [section:ellint_d Elliptic Integral D - Legendre Form]
- [heading Synopsis]
- ``
- #include <boost/math/special_functions/ellint_d.hpp>
- ``
- namespace boost { namespace math {
- template <class T1, class T2>
- ``__sf_result`` ellint_d(T1 k, T2 phi);
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_d(T1 k, T2 phi, const ``__Policy``&);
- template <class T1>
- ``__sf_result`` ellint_d(T1 k);
- template <class T1, class ``__Policy``>
- ``__sf_result`` ellint_d(T1 k, const ``__Policy``&);
- }} // namespaces
-
- [heading Description]
- These two functions evaluate the incomplete elliptic integral
- ['D([phi], k)] and its complete counterpart ['D(k) = D([pi]/2, k)].
- The return type of these functions is computed using the __arg_promotion_rules
- when the arguments are of different types: when they are the same type then the result
- is the same type as the arguments.
- template <class T1, class T2>
- ``__sf_result`` ellint_d(T1 k, T2 phi);
-
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` ellint_3(T1 k, T2 phi, const ``__Policy``&);
-
- Returns the incomplete elliptic integral:
- [equation ellint_d]
- Requires ['k[super 2]sin[super 2](phi) < 1], otherwise
- returns the result of __domain_error (outside this range the result
- would be complex).
- [optional_policy]
- template <class T1>
- ``__sf_result`` ellint_d(T1 k);
-
- template <class T1, class ``__Policy``>
- ``__sf_result`` ellint_d(T1 k, const ``__Policy``&);
-
- Returns the complete elliptic integral ['D(k) = D([pi]/2, k)]
- Requires ['-1 <= k <= 1] otherwise returns the
- result of __domain_error (outside this range the result would be complex).
- [optional_policy]
- [heading Accuracy]
- These functions are trivially computed in terms of other elliptic integrals
- and generally have very low error rates (a few epsilon) unless parameter [phi]
- is very large, in which case the usual trigonometric function argument-reduction issues apply.
- [table_ellint_d_complete_]
- [table_ellint_d]
- The following error plot are based on an exhaustive search of the functions domain, MSVC-15.5 at `double` precision,
- and GCC-7.1/Ubuntu for `long double` and `__float128`.
- [graph elliptic_integral_d__double]
- [graph elliptic_integral_d__80_bit_long_double]
- [graph elliptic_integral_d____float128]
- [heading Testing]
- The tests use a mixture of spot test values calculated using
- values calculated at __WolframAlpha, and random test data generated using
- MPFR at 1000-bit precision and a deliberately naive implementation in terms of
- the Legendre integrals.
- [heading Implementation]
- The implementation for D([phi], k) first performs argument reduction using the relations:
- [expression ['D(-[phi], k) = -D([phi], k)]]
- and
- [expression ['D(n[pi]+[phi], k) = 2nD(k) + D([phi], k)]]
- to move [phi] to the range \[0, [pi]\/2\].
- The functions are then implemented in terms of Carlson's integral R[sub D]
- using the relation:
- [equation ellint_d]
- [endsect] [/section:ellint_d Elliptic Integral D - Legendre Form]
- [section:jacobi_zeta Jacobi Zeta Function]
- [heading Synopsis]
- ``
- #include <boost/math/special_functions/jacobi_zeta.hpp>
- ``
- namespace boost { namespace math {
- template <class T1, class T2>
- ``__sf_result`` jacobi_zeta(T1 k, T2 phi);
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` jacobi_zeta(T1 k, T2 phi, const ``__Policy``&);
- }} // namespaces
-
- [heading Description]
- This function evaluates the Jacobi Zeta Function ['Z([phi], k)]
- [equation jacobi_zeta]
- Please note the use of [phi], and /k/ as the parameters, the function is often defined as ['Z([phi], m)]
- with ['m = k[super 2]], see for example [@http://mathworld.wolfram.com/JacobiZetaFunction.html Weisstein, Eric W. "Jacobi Zeta Function." From MathWorld--A Wolfram Web Resource.]
- Or else as [@https://dlmf.nist.gov/22.16#E32 ['Z(x, k)]] with ['[phi] = am(x, k)],
- where ['am] is the [@https://dlmf.nist.gov/22.16#E1 Jacobi amplitude function]
- which is equivalent to ['asin(jacobi_elliptic(k, x))].
- The return type of this function is computed using the __arg_promotion_rules
- when the arguments are of different types: when they are the same type then the result
- is the same type as the arguments.
- Requires ['-1 <= k <= 1], otherwise
- returns the result of __domain_error (outside this range the result would be complex).
- [optional_policy]
- Note that there is no complete analogue of this function (where [phi] = [pi] / 2)
- as this takes the value 0 for all ['k].
- [heading Accuracy]
- These functions are trivially computed in terms of other elliptic integrals
- and generally have very low error rates (a few epsilon) unless parameter [phi]
- is very large, in which case the usual trigonometric function argument-reduction issues apply.
- [table_jacobi_zeta]
- [heading Testing]
- The tests use a mixture of spot test values calculated using
- values calculated at __WolframAlpha, and random test data generated using
- MPFR at 1000-bit precision and a deliberately naive implementation in terms of
- the Legendre integrals.
- [heading Implementation]
- The implementation for Z([phi], k) first makes the argument [phi] positive using:
- [expression ['Z(-[phi], k) = -Z([phi], k)]]
- The function is then implemented in terms of Carlson's integral R[sub J]
- using the relation:
- [equation jacobi_zeta]
- There is one special case where the above relation fails: when ['k = 1], in that case
- the function simplifies to
- [expression ['Z([phi], 1) = sign(cos([phi])) sin([phi])]]
- [h5:jacobi_zeta_example Example]
- A simple example comparing use of __WolframAlpha with Boost.Math (including much higher precision using Boost.Multiprecision)
- is [@../../example/jacobi_zeta_example.cpp jacobi_zeta_example.cpp].
- [endsect] [/section:jacobi_zeta Jacobi Zeta Function]
- [section:heuman_lambda Heuman Lambda Function]
- [heading Synopsis]
- ``
- #include <boost/math/special_functions/heuman_lambda.hpp>
- ``
- namespace boost { namespace math {
- template <class T1, class T2>
- ``__sf_result`` heuman_lambda(T1 k, T2 phi);
- template <class T1, class T2, class ``__Policy``>
- ``__sf_result`` heuman_lambda(T1 k, T2 phi, const ``__Policy``&);
- }} // namespaces
-
- [heading Description]
- This function evaluates the Heuman Lambda Function ['[Lambda][sub 0]([phi], k)]
- [equation heuman_lambda]
- The return type of this function is computed using the __arg_promotion_rules
- when the arguments are of different types: when they are the same type then the result
- is the same type as the arguments.
- Requires ['-1 <= k <= 1], otherwise
- returns the result of __domain_error (outside this range the result would be complex).
- [optional_policy]
- Note that there is no complete analogue of this function (where [phi] = [pi] / 2)
- as this takes the value 1 for all ['k].
- [heading Accuracy]
- These functions are trivially computed in terms of other elliptic integrals
- and generally have very low error rates (a few epsilon) unless parameter [phi]
- is very large, in which case the usual trigonometric function argument-reduction issues apply.
- [table_heuman_lambda]
- [heading Testing]
- The tests use a mixture of spot test values calculated using
- values calculated at __WolframAlpha, and random test data generated using
- MPFR at 1000-bit precision and a deliberately naive implementation in terms of
- the Legendre integrals.
- [heading Implementation]
- The function is then implemented in terms of Carlson's integrals R[sub J] and R[sub F]
- using the relation:
- [equation heuman_lambda]
- This relation fails for ['|[phi]| >= [pi]/2] in which case the definition in terms of the
- Jacobi Zeta is used.
- [endsect] [/section:heuman_lambda Heuman Lambda Function]
|