BubbleProfiler  0.3.0
by Peter Athron, Csaba Balazs, Michael Bardsley, Andrew Fowlie, Dylan Harries & Graham White
numeric.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of BubbleProfiler.
3  *
4  * BubbleProfiler is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * BubbleProfiler is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with BubbleProfiler. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
24 #include "numeric.hpp"
25 #include "math_wrappers.hpp"
26 
27 namespace BubbleProfiler {
28 
29 double area_n_sphere(int n) {
30  double v = 1.;
31  double s = 2.;
32  for (int i = 1; i <= n; ++i) {
33  const double s_n = 2. * Pi * v;
34  const double v_n = s / i;
35  s = s_n;
36  v = v_n;
37  }
38  return s;
39 }
40 
41 double Wm1(double a) {
52  const std::complex<double> ca(a, 0.);
53  const std::complex<double> l1 = Log(ca);
54  const std::complex<double> l2 = Log(l1);
55  const std::complex<double> sum = l1 - l2
56  + l2 / l1
57  + 0.5 * l2 * (-2. + l2) / std::pow(l1, 2)
58  + l2 * (6. - 9. * l2 + 2. * std::pow(l2, 2)) / (6. * std::pow(l1, 3))
59  + l2 * (-12. + 36. * l2 - 22. * std::pow(l2, 2) + 3. * std::pow(l2, 2)) / (12. * std::pow(l1, 4));
60  return Re(sum);
61 }
62 
63 double asinch(double a) {
64  if (a <= 1.5) {
65  // Taylor expansion
66  return Sqrt(6. * (a - 1.));
67  } else {
68  // Lambert W-function solution
69  return -Wm1(-0.5 / a);
70  }
71 }
72 
73 double series(double a) {
84  return 2. * a + 3. * std::pow(a, 3) / 10. + 321. * std::pow(a, 5) / 2800. + 3197. * std::pow(a, 7) / 56000. +
85  445617. * std::pow(a, 9) / 13798400. + 1766784699. * std::pow(a, 11) / 89689600000. +
86  317184685563. * std::pow(a, 13) / 25113088000000. +
87  14328608561991. * std::pow(a, 15) / 1707689984000000. +
88  6670995251837391. * std::pow(a, 17) / 1165411287040000000. +
89  910588298588385889. * std::pow(a, 19) / 228420612259840000000.;
90 }
91 
92 double asinc(double a) {
93  return Sqrt(3. / 2.) * series(Sqrt(1. - a));
94 }
95 
96 double approx_root_pos_4(double a) {
97  if (a < 1.) {
98  // Taylor expansion
99  return 4. * Sqrt(a);
100  } else {
101  // Lambert W-function solution
102  const double arg = - 2. / 3. * std::pow(2. / Pi, 1. / 3.)
103  / std::pow(1. + 2. * a, 2. / 3.);
104  return -1.5 * Wm1(arg);
105  }
106 }
107 
108 double approx_root_neg_4(double a) {
109  return 4. * Sqrt(a);
110 }
111 
112 } // namespace BubbleProfiler
T Log(T x) noexcept
double approx_root_neg_4(double a)
Definition: numeric.cpp:108
double series(double a)
Definition: numeric.cpp:73
T Sqrt(T x) noexcept
double approx_root_pos_4(double a)
Definition: numeric.cpp:96
T Re(T x) noexcept
double asinch(double a)
Definition: numeric.cpp:63
double area_n_sphere(int n)
Definition: numeric.cpp:29
double asinc(double a)
Definition: numeric.cpp:92
Numerical functions for one-dimensional shooting method and area of -sphere.
double Wm1(double a)
Definition: numeric.cpp:41