v0.15.5
Loading...
Searching...
No Matches
lambert_w_sing.hpp
Go to the documentation of this file.
1
2// Copyright Balazs Cziraki 2016.
3// Use, modification and distribution are subject to the
4// Boost Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_MATH_LAMBERT_W_SING_HPP_INCLUDED
8#define BOOST_MATH_LAMBERT_W_SING_HPP_INCLUDED
9
10#include <boost/array.hpp>
11#include "lambert_w_tools.hpp"
12
13namespace boost
14{
15namespace math
16{
17namespace lambw
18{
19 //Constant that controls series evaluation length
20 const std::size_t _sing_series_L = 9;
21
22 //The following functions calculate the coefficients for the series expansion
23 //of W(z) and W_{+-1}(z) for abs(z-exp(-1))<exp(-1), or in other words: around the singularity at z=-exp(-1)
24 template<class CoeffType>
25 /*BOOST_CONSTEXPR*/ CoeffType _sing_coeffs_mu(std::size_t k);
26
27 template<class CoeffType>
28 /*BOOST_CONSTEXPR*/ CoeffType _sing_coeffs_alpha(std::size_t k)
29 {
30 if(k == 0)
31 {
32 return 2.;
33 }
34 else if(k == 1)
35 {
36 return -1.;
37 }
38 else
39 {
40 CoeffType sum = 0;
41 for(std::size_t j = 2; j <= (k-1); ++j)
42 {
43 sum+=_sing_coeffs_mu<CoeffType>(j)*_sing_coeffs_mu<CoeffType>(k+1-j);
44 }
45 return sum;
46 }
47 }
48
49 template<class CoeffType>
50 /*BOOST_CONSTEXPR*/ CoeffType _sing_coeffs_mu(std::size_t k)
51 {
52 if(k == 0)
53 {
54 return -1.;
55 }
56 else if(k == 1)
57 {
58 return 1.;
59 }
60 else
61 {
62 return (_sing_coeffs_mu<CoeffType>(k-2)/2
63 +_sing_coeffs_alpha<CoeffType>(k-2)/4)*(k-1)/(k+1)
64 -_sing_coeffs_alpha<CoeffType>(k)/2
65 -_sing_coeffs_mu<CoeffType>(k-1)/(k+1);
66 }
67 }
68
69 template<class CoeffType>
70 /*BOOST_CONSTEXPR*/ CoeffType _sing_coeffs(std::size_t k)
71 {
72 CoeffType ans = _sing_coeffs_mu<CoeffType>(k+1)/_sing_coeffs_mu<CoeffType>(k);
73 return ans;
74 }
75
76 //Array to store the coefficients for the singularity series expansion
77 template<class CoeffType>
78 inline const boost::array<CoeffType,_sing_series_L>& _lw_singc()
79 {
80 static const boost::array<CoeffType,_sing_series_L> ans = _coeff_array<CoeffType,_sing_series_L>(_sing_coeffs<CoeffType>);
81 return ans;
82 }
83
84 //Calculates an approximation for W(z) around the singularity at z=-exp(-1) in an exp(-1) radius.
85 template<class ArgumentType, class CoeffType, class IndexType>
86 ArgumentType _sing(const ArgumentType &z, IndexType k)
87 {
88 using std::pow;
89 using std::sqrt;
90 using std::exp;
91 using std::log;
92
93 ArgumentType p;
94
95 p = ((CoeffType)pow(-1.,k%2))*sqrt((CoeffType)2.*(boost::math::constants::e<CoeffType>()*z+(CoeffType)1.));
96
97 /*
98 if(_complex_real(z) >= 0)
99 {
100 p = ((CoeffType)pow(-1.,k%2))*sqrt((CoeffType)2.*(exp((CoeffType)1.+log(z))+(CoeffType)1.));
101 }
102 else
103 {
104 p = ((CoeffType)pow(-1.,k%2))*sqrt((CoeffType)2.*(-exp((CoeffType)1.+log(-z))+(CoeffType)1.));
105 }
106 */
107
108 return -_series_sum(p,_lw_singc<CoeffType>());
109 }
110} //namespace lambw
111} //namespace math
112} //namespace boost
113
114#endif // BOOST_MATH_LAMBERT_W_SING_HPP_INCLUDED
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
CoeffType _sing_coeffs_mu(std::size_t k)
ArgumentType _sing(const ArgumentType &z, IndexType k)
const std::size_t _sing_series_L
CoeffType _sing_coeffs(std::size_t k)
ArgumentType _series_sum(const ArgumentType &z, const boost::array< CoeffType, L > &c)
CoeffType _sing_coeffs_alpha(std::size_t k)
const boost::array< CoeffType, _sing_series_L > & _lw_singc()