mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Change to use JM W0 version.
This commit is contained in:
@@ -60,27 +60,25 @@ int main()
|
||||
|
||||
std::cout.precision(std::numeric_limits<double>::max_digits10);
|
||||
|
||||
// for (double z = -0.3678794411714423215955237701614608727; z < 2.8; z += 0.001)
|
||||
int count = 0;
|
||||
for (double z = -0.36787944117144232159552377016146086744581113103176804; z < 1.; z += 0.001)
|
||||
for (double z = -0.36787944117144232159552377016146086744581113103176804; z < 2.8; z += 0.001)
|
||||
{
|
||||
double w0 = jm_lambert_w0(z);
|
||||
//double w0 = lambert_w0(z);
|
||||
w0s[z] = w0;
|
||||
std::cout << "z " << z << ", w = " << w0 << std::endl;
|
||||
// std::cout << "z " << z << ", w = " << w0 << std::endl;
|
||||
count++;
|
||||
}
|
||||
std::cout << "points " << count << std::endl;
|
||||
|
||||
//count = 0;
|
||||
//for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001)
|
||||
//{
|
||||
// double wm1 = lambert_wm1(z);
|
||||
// wm1s[z] = wm1;
|
||||
// count++;
|
||||
//}
|
||||
//std::cout << "points " << count << std::endl;
|
||||
|
||||
count = 0;
|
||||
for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001)
|
||||
{
|
||||
double wm1 = lambert_wm1(z);
|
||||
wm1s[z] = wm1;
|
||||
count++;
|
||||
}
|
||||
std::cout << "points " << count << std::endl;
|
||||
|
||||
svg_2d_plot data_plot;
|
||||
svg_2d_plot data_plot2;
|
||||
@@ -112,8 +110,6 @@ int main()
|
||||
//.background_border_color(black);
|
||||
;
|
||||
|
||||
|
||||
|
||||
// bigger W
|
||||
for (double z = -0.3678794411714423215955237701614608727; z < 10000.; z += 50.)
|
||||
{
|
||||
@@ -123,17 +119,17 @@ int main()
|
||||
}
|
||||
std::cout << "points " << count << std::endl;
|
||||
|
||||
//count = 0;
|
||||
//for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001)
|
||||
//{
|
||||
// double wm1 = lambert_wm1(z);
|
||||
// wm1s_big[z] = wm1;
|
||||
// count++;
|
||||
//}
|
||||
//std::cout << "points " << count << std::endl;
|
||||
count = 0;
|
||||
for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001)
|
||||
{
|
||||
double wm1 = lambert_wm1(z);
|
||||
wm1s_big[z] = wm1;
|
||||
count++;
|
||||
}
|
||||
std::cout << "points " << count << std::endl;
|
||||
|
||||
data_plot.plot(w0s, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1);
|
||||
// data_plot.plot(wm1s, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
|
||||
data_plot.plot(wm1s, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
|
||||
data_plot.write("./lambert_w_graph");
|
||||
|
||||
data_plot2.title("Lambert W function for larger z.")
|
||||
@@ -164,7 +160,7 @@ int main()
|
||||
;
|
||||
|
||||
data_plot2.plot(w0s_big, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1);
|
||||
//data_plot2.plot(wm1s_big, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
|
||||
data_plot2.plot(wm1s_big, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
|
||||
data_plot2.write("./lambert_w_graph_big_w");
|
||||
|
||||
// bezier_on(true); // ???
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,24 @@
|
||||
// Copyright Paul A. Bristow 2017.
|
||||
// Distributed under 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)
|
||||
|
||||
// I:/modular-boost/libs/math/include/boost/math/special_functions/lambert_w_lookup_table.ipp
|
||||
// A collection of 128-bit precision integral Lambert W values computed using 37 decimal digits precision.
|
||||
|
||||
// A collection of 128-bit precision integral z argument Lambert W values computed using 37 decimal digits precision.
|
||||
// C++ floating-point precision is 128-bit long double.
|
||||
// Output as 53 decimal digits, suffixed L.
|
||||
|
||||
// C++ floating-point type is provided by lambert_w.hpp typedef.
|
||||
// For example: typedef lookup_t double; (or float or long double)
|
||||
|
||||
// Written by I:\modular-boost\libs\math\test\lambert_w_lookup_table_generator.cpp Fri Nov 3 11:56:21 2017
|
||||
|
||||
// Copyright Paul A. Bristow 2017.
|
||||
// Distributed under 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)
|
||||
// Written by I:\modular-boost\libs\math\test\lambert_w_lookup_table_generator.cpp Thu Jan 25 16:52:07 2018
|
||||
|
||||
// Sizes of arrays of z values for Lambert W[0], W[1] ... W[64]"nand W[-1], W[-2] ... W[-64].
|
||||
|
||||
namespace boost {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
namespace lambert_w_detail {
|
||||
namespace lambert_w_lookup
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR std::size_t noof_sqrts = 12;
|
||||
|
||||
1662
include/boost/math/special_functions/lambert_w_pb.hpp
Normal file
1662
include/boost/math/special_functions/lambert_w_pb.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,29 @@
|
||||
# Copyright John Maddock 2010
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# Copyright Paul A. Bristow 2018
|
||||
# Distributed under 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.
|
||||
# \math_toolkit\libs\math\test\jamfile.v2
|
||||
# Runs all math toolkit tests, functions & distributions,
|
||||
# and build math examples.
|
||||
# \math_toolkit\libs\math\minimax\jamfile.v2
|
||||
# Runs minimax using multiprecision, (rather than gmp and mpfr)
|
||||
|
||||
# bring in the rules for testing
|
||||
# bring in the rules for testing.
|
||||
import modules ;
|
||||
import path ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc:<cxxflags>-Wno-missing-braces
|
||||
<toolset>darwin:<cxxflags>-Wno-missing-braces
|
||||
<toolset>acc:<cxxflags>+W2068,2461,2236,4070,4069
|
||||
<toolset>intel-win:<cxxflags>-nologo
|
||||
<toolset>intel-win:<linkflags>-nologo
|
||||
<toolset>intel-win:<cxxflags>-nologo
|
||||
<toolset>intel-win:<linkflags>-nologo
|
||||
<toolset>msvc:<warnings>all
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
<toolset>msvc:<cxxflags>/wd4996
|
||||
<toolset>msvc:<cxxflags>/wd4512
|
||||
<toolset>msvc:<cxxflags>/wd4610
|
||||
<toolset>msvc:<cxxflags>/wd4510
|
||||
<toolset>msvc:<cxxflags>/wd4127
|
||||
<toolset>msvc:<cxxflags>/wd4512
|
||||
<toolset>msvc:<cxxflags>/wd4610
|
||||
<toolset>msvc:<cxxflags>/wd4510
|
||||
<toolset>msvc:<cxxflags>/wd4127
|
||||
<toolset>msvc:<cxxflags>/wd4701 # needed for lexical cast - temporary.
|
||||
<link>static
|
||||
<toolset>borland:<runtime-link>static
|
||||
@@ -32,15 +32,15 @@ project
|
||||
<define>BOOST_UBLAS_UNSUPPORTED_COMPILER=0
|
||||
<include>.
|
||||
<include>../include_private
|
||||
<include>$(ntl-path)/include
|
||||
#<include>$(ntl-path)/include
|
||||
;
|
||||
|
||||
#lib mpfr : gmp : <name>mpfr ;
|
||||
|
||||
lib mpfr : gmp : <name>mpfr ;
|
||||
#lib gmp : : <name>gmp ;
|
||||
|
||||
lib gmp : : <name>gmp ;
|
||||
|
||||
exe minimax : f.cpp main.cpp gmp mpfr ;
|
||||
# exe minimax : f.cpp main.cpp gmp mpfr ;
|
||||
exe minimax : f.cpp main.cpp ;
|
||||
|
||||
install bin : minimax ;
|
||||
|
||||
|
||||
@@ -359,6 +359,7 @@ mp_type f(const mp_type& x, int variant)
|
||||
mp_type xx = 1 / x;
|
||||
return boost::math::cyl_bessel_k(1, xx) * sqrt(xx) * exp(xx);
|
||||
}
|
||||
// Lambert W0
|
||||
case 40:
|
||||
return boost::math::lambert_w0(x);
|
||||
case 41:
|
||||
|
||||
@@ -9,8 +9,15 @@
|
||||
//! to 34 decimal digits precision to cater for platforms that have 128-bit long double.
|
||||
//! The function bisection can then use any built-in floating-point type,
|
||||
//! which may have different precision and speed on different platforms.
|
||||
// The actual builtin floating-point type of the arrays is chosen by a typedef in lambert_W.hpp,
|
||||
// by default, for example: typedef double lookup_t;
|
||||
//! The actual builtin floating-point type of the arrays is chosen by a
|
||||
//! typedef in \modular-boost\libs\math\include\boost\math\special_functions\lambert_w.hpp
|
||||
//! by default, for example: typedef double lookup_t;
|
||||
|
||||
|
||||
// This includes lookup tables for both branches W0 and W-1.
|
||||
// Only W-1 is needed by current code that uses JM rational Polynomials,
|
||||
// but W0 is kept (for now) to allow comparison with the previous FKDVPB version
|
||||
// that uses lookup for W0 branch as well as W-1.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/math/constants/constants.hpp> // For exp_minus_one == 3.67879441171442321595523770161460867e-01.
|
||||
@@ -106,14 +113,14 @@ a: 1.6487212181091309 1.2840254306793213 1.1331484317779541 1.0644944906234741 1
|
||||
// These are common to both W0 and W-1
|
||||
b: 0.5 0.25 0.125 0.0625 0.03125 0.015625 0.0078125 0.00390625 0.001953125 0.0009765625 0.00048828125 0.000244140625
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// Creates if no file exists, & uses default overwrite/ ios::replace.
|
||||
const char filename[] = // "lambert_w_lookup_table.ipp";
|
||||
"I:/modular-boost/libs/math/include/boost/math/special_functions/lambert_w_lookup_table.ipp";
|
||||
//const char filename[] = // "lambert_w_lookup_table.ipp"; // Write to same folder as generator:
|
||||
//"I:/modular-boost/libs/math/include/boost/math/special_functions/lambert_w_lookup_table.ipp";
|
||||
const char filename[] = "lambert_w_lookup_table.ipp";
|
||||
|
||||
std::ofstream fout(filename, std::ios::out);
|
||||
std::ofstream fout(filename, std::ios::out); // File output stream.
|
||||
|
||||
// 128-bit precision type (so that full precision if long double type uses 128-bit).
|
||||
// typedef cpp_bin_float_quad table_lookup_t; // Output using max_digits10 for 37 decimal digit precision.
|
||||
@@ -126,7 +133,7 @@ typedef cpp_bin_float_50 table_lookup_t; // Compute tables to 50 decimla digit p
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Lambert W table lookup values to file." << std::endl;
|
||||
std::cout << "Lambert W table lookup values." << std::endl;
|
||||
if (!fout.is_open())
|
||||
{ // File failed to open OK.
|
||||
std::cerr << "Open file " << filename << " failed!" << std::endl;
|
||||
@@ -139,8 +146,13 @@ int main()
|
||||
int output_precision = std::numeric_limits<cpp_bin_float_quad>::max_digits10; // 37 decimal digits.
|
||||
fout.precision(output_precision);
|
||||
fout <<
|
||||
"// " << filename << "\n"
|
||||
"// A collection of 128-bit precision integral Lambert W values computed using "
|
||||
"// Copyright Paul A. Bristow 2017." "\n"
|
||||
"// Distributed under the Boost Software License, Version 1.0." "\n"
|
||||
"// (See accompanying file LICENSE_1_0.txt" "\n"
|
||||
"// or copy at http://www.boost.org/LICENSE_1_0.txt)" "\n"
|
||||
"\n"
|
||||
"// " << filename << "\n\n"
|
||||
"// A collection of 128-bit precision integral z argument Lambert W values computed using "
|
||||
<< output_precision << " decimal digits precision.\n"
|
||||
"// C++ floating-point precision is 128-bit long double.\n"
|
||||
"// Output as "
|
||||
@@ -152,18 +164,12 @@ int main()
|
||||
|
||||
"\n"
|
||||
"// Written by " << __FILE__ << " " << __TIMESTAMP__ << "\n"
|
||||
|
||||
"\n"
|
||||
"// Copyright Paul A. Bristow 2017." "\n"
|
||||
"// Distributed under the Boost Software License, Version 1.0." "\n"
|
||||
"// (See accompanying file LICENSE_1_0.txt" "\n"
|
||||
"// or copy at http://www.boost.org/LICENSE_1_0.txt)" "\n"
|
||||
<< std::endl;
|
||||
|
||||
fout << "// Sizes of arrays of z values for Lambert W[0], W[1] ... W[64]"
|
||||
"\"n""and W[-1], W[-2] ... W[-64]." << std::endl;
|
||||
|
||||
fout << "\nnamespace boost {\nnamespace math {\nnamespace detail {\nnamespace lambert_w_lookup\n{ \n";
|
||||
fout << "\nnamespace boost {\nnamespace math {\nnamespace lambert_w_detail {\nnamespace lambert_w_lookup\n{ \n";
|
||||
|
||||
BOOST_STATIC_CONSTEXPR std::size_t noof_sqrts = 12;
|
||||
BOOST_STATIC_CONSTEXPR std::size_t noof_halves = 12;
|
||||
@@ -430,13 +436,12 @@ int main()
|
||||
}
|
||||
fout << "\n}; // wm1zs" << std::endl;
|
||||
|
||||
fout << "} // namespace lambert_w_lookup\n} // namespace detail\n} // namespace math\n} // namespace boost" << std::endl;
|
||||
fout << "} // namespace lambert_w_lookup\n} // namespace lambert_w_detail\n} // namespace math\n} // namespace boost" << std::endl;
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
std::cout << "Exception " << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
fout.close();
|
||||
return 0;
|
||||
|
||||
@@ -446,11 +451,8 @@ int main()
|
||||
|
||||
Original arrays as output by Veberic/Fukushima code:
|
||||
|
||||
|
||||
w0 branch
|
||||
|
||||
|
||||
|
||||
W-1 branch
|
||||
|
||||
e: 2.7182818284590451 7.3890560989306495 20.085536923187664 54.598150033144229 148.41315910257657 403.42879349273500 1096.6331584284583 2980.9579870417274 8103.0839275753815 22026.465794806707 59874.141715197788 162754.79141900383 442413.39200892020 1202604.2841647759 3269017.3724721079 8886110.5205078647 24154952.753575277 65659969.137330450 178482300.96318710 485165195.40978980 1318815734.4832134 3584912846.1315880 9744803446.2488918 26489122129.843441 72004899337.385788 195729609428.83853 532048240601.79797 1446257064291.4734 3931334297144.0371 10686474581524.447 29048849665247.383 78962960182680.578 214643579785915.75 583461742527454.00 1586013452313428.3 4311231547115188.5 11719142372802592. 31855931757113704. 86593400423993600. 2.3538526683701958e+17 6.3984349353005389e+17 1.7392749415204982e+18 4.7278394682293381e+18 1.2851600114359284e+19 3.4934271057485025e+19 9.4961194206024286e+19 2.5813128861900616e+20 7.0167359120976157e+20 1.9073465724950953e+21 5.1847055285870605e+21 1.4093490824269355e+22 3.8310080007165677e+22 1.0413759433029062e+23 2.8307533032746866e+23 7.6947852651419974e+23 2.0916594960129907e+24 5.6857199993359170e+24 1.5455389355900996e+25 4.2012104037905024e+25 1.1420073898156810e+26 3.1042979357019109e+26 8.4383566687414291e+26 2.2937831594696028e+27 6.2351490808115970e+27
|
||||
|
||||
@@ -30,15 +30,19 @@ using boost::multiprecision::cpp_dec_float_50;
|
||||
#include <boost/multiprecision/cpp_bin_float.hpp>
|
||||
//#include <boost/fixed_point/fixed_point.hpp> // If available.
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan, ifinite.
|
||||
#include <boost/math/special_functions/next.hpp> // float_next, float_prior
|
||||
using boost::math::float_next;
|
||||
using boost::math::float_prior;
|
||||
|
||||
#include <boost/math/tools/test_value.hpp> // for create_test_value and macro BOOST_MATH_TEST_VALUE.
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
using boost::math::policies::digits2;
|
||||
#include <boost/math/special_functions/lambert_w.hpp> // For Lambert W lambert_w function.
|
||||
//using boost::math::lambert_w0; // Use jm version instead
|
||||
using boost::math::lambert_wm1;
|
||||
|
||||
// #include "C:\Users\Paul\Desktop\lambert_w0 - Copy before amalgamation.hpp" // JM latest providing jm_lambert_w0 and jm_lambert_wm1
|
||||
#include "C:\Users\Paul\Desktop\lambert_w0.hpp" // JM latest providing jm_lambert_w0 and jm_lambert_wm1
|
||||
// #include "C:\Users\Paul\Desktop\lambert_w0 - Copy before amalgamation.hpp" // JM latest providing jm_lambert_w0 and lambert_wm1
|
||||
//#include "C:\Users\Paul\Desktop\lambert_w0.hpp" // JM latest providing jm_lambert_w0 and lambert_wm1
|
||||
using boost::math::lambert_wm1;
|
||||
using boost::math::lambert_w0; // Use jm version instead.
|
||||
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
@@ -116,7 +120,7 @@ void test_spots(RealType)
|
||||
// (Unused Parameter value, arbitrarily zero, only communicates the floating point type).
|
||||
// test_spots(0.F); test_spots(0.); test_spots(0.L);
|
||||
|
||||
using boost::math::jm_lambert_w0;
|
||||
using boost::math::lambert_w0;
|
||||
using boost::math::lambert_wm1;
|
||||
using boost::math::constants::exp_minus_one;
|
||||
using boost::math::constants::e;
|
||||
@@ -135,11 +139,11 @@ void test_spots(RealType)
|
||||
|
||||
// Test some bad parameters to the function, with default policy and with ignore_all policy.
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
BOOST_CHECK_THROW(jm_lambert_w0<RealType>(-1.), std::domain_error);
|
||||
BOOST_CHECK_THROW(lambert_w0<RealType>(-1.), std::domain_error);
|
||||
BOOST_CHECK_THROW(lambert_wm1<RealType>(-1.), std::domain_error);
|
||||
BOOST_CHECK_THROW(jm_lambert_w0<RealType>(std::numeric_limits<RealType>::quiet_NaN()), std::domain_error); // Would be NaN.
|
||||
BOOST_CHECK_THROW(lambert_w0<RealType>(std::numeric_limits<RealType>::quiet_NaN()), std::domain_error); // Would be NaN.
|
||||
// BOOST_CHECK_THROW(lambert_w0<RealType>(std::numeric_limits<RealType>::infinity()), std::domain_error); // Was if infinity should throw, now infinity.
|
||||
BOOST_CHECK_THROW(jm_lambert_w0<RealType>(-static_cast<RealType>(0.4)), std::domain_error); // Would be complex.
|
||||
BOOST_CHECK_THROW(lambert_w0<RealType>(-static_cast<RealType>(0.4)), std::domain_error); // Would be complex.
|
||||
#else // No exceptions so set policy to ignore and check result is NaN
|
||||
BOOST_MATH_CHECK_EQUAL(boost::math::lambert_w0<RealType>(std::numeric_limits<RealType>::quiet_NaN(), ignore_all_policy), std::numeric_limits<RealType::quiet_NaN()); // NaN.
|
||||
BOOST_MATH_CHECK_EQUAL(boost::math::lambert_w0<RealType>(std::numeric_limits<RealType>::infinity(), ignore_all_policy), std::numeric_limits<RealType::infinity()); // infinity.
|
||||
@@ -170,17 +174,17 @@ void test_spots(RealType)
|
||||
//std::cout << "singular_value " << singular_value << ", expected Lambert W = " << minus_one_value << std::endl;
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check -exp(-1) = -0.367879450 = -1
|
||||
jm_lambert_w0(singular_value),
|
||||
lambert_w0(singular_value),
|
||||
minus_one_value,
|
||||
tolerance); // OK
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check -exp(-1) ~= -0.367879450 == -1
|
||||
jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36787944117144232159552377016146086744581113103176783450783680169746149574489980335714727434591964374662732527)),
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36787944117144232159552377016146086744581113103176783450783680169746149574489980335714727434591964374662732527)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -1.),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check -exp(-1) ~= -0.367879450 == -1
|
||||
jm_lambert_w0<RealType>(-exp_minus_one<RealType>()),
|
||||
lambert_w0<RealType>(-exp_minus_one<RealType>()),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -1.),
|
||||
tolerance);
|
||||
|
||||
@@ -191,70 +195,70 @@ void test_spots(RealType)
|
||||
|
||||
// At branch junction singularity.
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check -exp(-1) ~= -0.367879450 == -1
|
||||
jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36787944117144232159552377016146086744581113103176783450783680169746149574489980335714727434591964374662732527)),
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36787944117144232159552377016146086744581113103176783450783680169746149574489980335714727434591964374662732527)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -1.),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.1)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.1)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.091276527160862264299895721423179568653119224051472),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(0.2)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.2)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.2)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.16891597349910956511647490370581839872844691351073),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(0.2)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.5)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.5)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.351733711249195826024909300929951065171464215517111804046),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(0.5)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(
|
||||
jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.)),
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.56714329040978387299996866221035554975381578718651),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(1)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 2.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 2.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.852605502013725491346472414695317466898453300151403508772),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(2.)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.049908894964039959988697070552897904589466943706341452932),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(3.)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 5.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 5.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.326724665242200223635099297758079660128793554638047479789),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(0.5)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 6.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 6.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.432404775898300311234078007212058694786434608804302025655),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(6)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 100.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 100.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 3.3856301402900501848882443645297268674916941701578),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(100)
|
||||
tolerance);
|
||||
|
||||
if (std::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
// BOOST_CHECK_THROW(jm_lambert_w0(std::numeric_limits<RealType>::infinity()), std::domain_error); // If should throw exception.
|
||||
//BOOST_CHECK_EQUAL(jm_lambert_w0(std::numeric_limits<RealType>::infinity()), +std::numeric_limits<RealType>::infinity()); // message is:
|
||||
// BOOST_CHECK_THROW(lambert_w0(std::numeric_limits<RealType>::infinity()), std::domain_error); // If should throw exception.
|
||||
//BOOST_CHECK_EQUAL(lambert_w0(std::numeric_limits<RealType>::infinity()), +std::numeric_limits<RealType>::infinity()); // message is:
|
||||
// Error in "test_types": class boost::exception_detail::clone_impl<struct boost::exception_detail::error_info_injector<class std::domain_error> > :
|
||||
// Error in function boost::math::lambert_w0<RealType>(<RealType>) : Argument z is infinite!
|
||||
//BOOST_CHECK_EQUAL(jm_lambert_w0(std::numeric_limits<RealType>::infinity()), +std::numeric_limits<RealType>::infinity()); // If infinity allowed.
|
||||
//BOOST_CHECK_EQUAL(lambert_w0(std::numeric_limits<RealType>::infinity()), +std::numeric_limits<RealType>::infinity()); // If infinity allowed.
|
||||
BOOST_CHECK_THROW(lambert_wm1(std::numeric_limits<RealType>::infinity()), std::domain_error); // Infinity NOT allowed.
|
||||
}
|
||||
if (std::numeric_limits<RealType>::has_quiet_NaN)
|
||||
{ // Argument Z == NaN is always an throwable error for both branches.
|
||||
// BOOST_CHECK_EQUAL(jm_lambert_w0(std::numeric_limits<RealType>::quiet_NaN()), +std::numeric_limits<RealType>::infinity()); // message is:
|
||||
// BOOST_CHECK_EQUAL(lambert_w0(std::numeric_limits<RealType>::quiet_NaN()), +std::numeric_limits<RealType>::infinity()); // message is:
|
||||
// Error in function boost::math::lambert_w0<RealType>(<RealType>): Argument z is NaN!
|
||||
BOOST_CHECK_THROW(jm_lambert_w0(std::numeric_limits<RealType>::quiet_NaN()), std::domain_error);
|
||||
BOOST_CHECK_THROW(lambert_w0(std::numeric_limits<RealType>::quiet_NaN()), std::domain_error);
|
||||
BOOST_CHECK_THROW(lambert_wm1(std::numeric_limits<RealType>::quiet_NaN()), std::domain_error);
|
||||
}
|
||||
|
||||
@@ -280,14 +284,14 @@ void test_spots(RealType)
|
||||
|
||||
// Just using series approximation (switch at -0.35).
|
||||
// N[productlog(-0.351), 50] = -0.72398644140937651483634596143951001600417138085814
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.351)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.351)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.72398644140937651483634596143951001600417138085814),
|
||||
// 2 * tolerance); // Note 2 * tolerance for PB fukushima
|
||||
// got -0.723986441409376931150560229265736446 without Halley
|
||||
// exp -0.72398644140937651483634596143951001
|
||||
// got -0.72398644140937651483634596143951029 with Halley
|
||||
// -0.723987103 JM 4.7126390815771382 3.13946001911235553672 3.13946001911235553658372193565165217
|
||||
2 * tolerance); // expect -0.72398644140937651 but get 4.7126390815771382 for JM????
|
||||
10 * tolerance); // expect -0.72398644140937651 float -0.723987103 needs 10 * tolerance
|
||||
// 2 * tolerance is fine for double and up.
|
||||
// Float is OK
|
||||
|
||||
// Same for W-1 branch
|
||||
@@ -366,33 +370,140 @@ void test_spots(RealType)
|
||||
}
|
||||
if (std::numeric_limits<RealType>::has_quiet_NaN)
|
||||
{
|
||||
// BOOST_CHECK_EQUAL(jm_lambert_w0(std::numeric_limits<RealType>::quiet_NaN()), +std::numeric_limits<RealType>::infinity()); // message is:
|
||||
// BOOST_CHECK_EQUAL(lambert_w0(std::numeric_limits<RealType>::quiet_NaN()), +std::numeric_limits<RealType>::infinity()); // message is:
|
||||
// Error in function boost::math::lambert_w0<RealType>(<RealType>): Argument z is NaN!
|
||||
BOOST_CHECK_THROW(lambert_wm1(std::numeric_limits<RealType>::quiet_NaN()), std::domain_error);
|
||||
}
|
||||
|
||||
// W0 Tests for too big and too small to use lookup table.
|
||||
// Exactly W = 64, not enough to be OK for lookup.
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.9904954117194348050619127737142206366920907815909119e+29)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.9904954117194348050619127737142206366920907815909119e+29)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 64.0),
|
||||
tolerance);
|
||||
|
||||
// Just below z for F[64]
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.99045411719434e+29)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.99045411719434e+29)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 63.999989810930513468726486827408823607175844852495), tolerance);
|
||||
// Fails for quad_float -1.22277013397850595265
|
||||
// -1.22277013397850595319
|
||||
|
||||
// Just too big, so using log approx and Halley refinement.
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 4e+29)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 4e+29)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 64.002342375637950350970694519073803643686041499677),
|
||||
tolerance);
|
||||
|
||||
// Check at reduced precision.
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 4e+29), policy<digits2<11> >()),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 4e+29), policy<digits2<11> >()),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 64.002342375637950350970694519073803643686041499677),
|
||||
0.00002); // 0.00001 fails.
|
||||
|
||||
// Tests to ensure that all JM rational polynomials are being checked.
|
||||
|
||||
// 1st polynomal if (z < 0.5) // 0.05 < z < 0.5
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.49)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.3465058086974944293540338951489158955895910665452626949),
|
||||
tolerance);
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.051)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.04858156174600359264950777241723801201748517590507517888),
|
||||
tolerance);
|
||||
|
||||
|
||||
|
||||
// 2st polynomal if 0.5 < z < 2
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.51)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.3569144916935871518694242462560450385494399307379277704),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.9)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.8291763302658400337004358009672187071638421282477162293),
|
||||
tolerance);
|
||||
|
||||
// 3rd polynomials 2 < z < 6
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 2.1)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.8752187586805470099843211502166029752154384079916131962),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 5.9)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.422521411785098213935338853943459424120416844150520831),
|
||||
tolerance);
|
||||
|
||||
// 4th polynomials 6 < z < 18
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 6.1)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.442152194116056579987235881273412088690824214100254315),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 17.9)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 2.129100923757568114366514708174691237123820852409339147),
|
||||
tolerance);
|
||||
|
||||
// 5th polynomials if (z < 9897.12905874) // 2.8 < log(z) < 9.2
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 18.1)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 2.136665501382339778305178680563584563343639180897328666),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 9897.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 7.222751047988674263127929506116648714752441161828893633),
|
||||
tolerance);
|
||||
|
||||
// 6th polynomials if (z < 7.896296e+13) // 9.2 < log(z) <= 32
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 9999.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 7.231758181708737258902175236106030961433080976032516996),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 7.7e+13)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 28.62069643025822480911439831021393125282095606713326376),
|
||||
tolerance);
|
||||
|
||||
// 7th polynomial // 32 < log(z) < 100
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 8.0e+18)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 39.84107480517853176296156400093560722439428484537515586),
|
||||
tolerance);
|
||||
|
||||
// Largest 32-bit float. (Larger values for other types tested using max())
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.e38)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 83.07844821316409592720410446942538465411465113447713574),
|
||||
tolerance);
|
||||
|
||||
// Small z < 0.05 if (z < -0.051) -0.27 < z < -0.051
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.28)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.4307588745271127579165306568413721388196459822705155385),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.05)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.05270598355154634795995650617915721289427674396592395160),
|
||||
tolerance);
|
||||
|
||||
// Using z small series function < 0.05
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.049)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.04676143671340832342497289393737051868103596756298863555),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.049)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.05159448479219405354564920228913331280713177046648170658),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1e-6)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 9.999990000014999973333385416558666900096702096424344715e-7),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -1e-6)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -1.000001000001500002666671875010800023343107568372593753e-6),
|
||||
tolerance);
|
||||
|
||||
// Near Smallest float.
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1e-38)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 9.99999999999999999999999999999999999990000000000000000e-39),
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -1e-38)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -1.000000000000000000000000000000000000010000000000000000e-38),
|
||||
tolerance);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Similar too near zero tests for W-1 branch
|
||||
// lambert_wm1(-1.0264389699511283e-26) = -64.000000000000000
|
||||
// Exactly z for W=-64
|
||||
@@ -438,7 +549,7 @@ void test_spots(RealType)
|
||||
BOOST_CHECK_THROW(lambert_wm1(-0.5), std::domain_error);
|
||||
|
||||
// This fails for fixed_point type used for other tests because out of range?
|
||||
//BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.0e6)),
|
||||
//BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.0e6)),
|
||||
//BOOST_MATH_TEST_VALUE(RealType, 11.383358086140052622000156781585004289033774706019),
|
||||
//// Output from https://www.wolframalpha.com/input/?i=lambert_w0(1e6)
|
||||
//// tolerance * 1000); // fails for fixed_point type exceeds 0.00015258789063
|
||||
@@ -448,7 +559,7 @@ void test_spots(RealType)
|
||||
// So need to use some spot tests for specific types, or use a bigger fixed_point type.
|
||||
|
||||
// Check zero.
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.0)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.0)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.0),
|
||||
tolerance);
|
||||
// these fail for cpp_dec_float_50
|
||||
@@ -494,7 +605,7 @@ BOOST_AUTO_TEST_CASE(test_types)
|
||||
BOOST_AUTO_TEST_CASE(test_range_of_double_values)
|
||||
{
|
||||
using boost::math::constants::exp_minus_one;
|
||||
using boost::math::jm_lambert_w0;
|
||||
using boost::math::lambert_w0;
|
||||
|
||||
BOOST_TEST_MESSAGE("\nTest Lambert W function type double for range of values.");
|
||||
|
||||
@@ -508,25 +619,25 @@ BOOST_AUTO_TEST_CASE(test_range_of_double_values)
|
||||
// tolerance);
|
||||
// So this section just tests a single type, say IEEE 64-bit double, for a range of spot values.
|
||||
|
||||
typedef double RealType;
|
||||
typedef double RealType; // Some tests assume type is double.
|
||||
|
||||
int epsilons = 1;
|
||||
RealType tolerance = boost::math::tools::epsilon<RealType>() * epsilons; // 2 eps as a fraction.
|
||||
std::cout << "Tolerance " << epsilons << " * epsilon == " << tolerance << std::endl;
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.0e-6)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.0e-6)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 9.9999900000149999733333854165586669000967020964243e-7),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[1e-6],50])
|
||||
tolerance);
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.0001)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.0001)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.000099990001499733385405869000452213835767629477903460),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[0.001],50])
|
||||
tolerance);
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.001)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.001)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.00099900149733853088995782787410778559957065467928884),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[0.001],50])
|
||||
tolerance);
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.01)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.01)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.0099014738435950118853363268165701079536277464949174),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[0.01],50])
|
||||
tolerance * 25); // <<< Needs a much bigger tolerance???
|
||||
@@ -539,58 +650,58 @@ BOOST_AUTO_TEST_CASE(test_range_of_double_values)
|
||||
// 0.00990728209160670 approx
|
||||
// 0.00990147384359511 previous
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.05)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.05)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.047672308600129374726388900514160870747062965933891),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[0.01],50])
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.1)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 0.1)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.091276527160862264299895721423179568653119224051472),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[1],50])
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.56714329040978387299996866221035554975381578718651),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[1],50])
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 2.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 2.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 0.852605502013725491346472414695317466898453300151403508772),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(2.)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 3.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.049908894964039959988697070552897904589466943706341452932),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(3.)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 5.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 5.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.326724665242200223635099297758079660128793554638047479789),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(0.5)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 6.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 6.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.432404775898300311234078007212058694786434608804302025655),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(6)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 10.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 10.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 1.7455280027406993830743012648753899115352881290809),
|
||||
// Output from https://www.wolframalpha.com/input/ N[lambert_w[10],50])
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 100.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 100.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 3.3856301402900501848882443645297268674916941701578),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(100)
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1000.)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1000.)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 5.2496028524015962271260563196973062825214723860596),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(1000)
|
||||
tolerance);
|
||||
|
||||
// This fails for fixed_point type used for other tests because out of range of the type?
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.0e6)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, 1.0e6)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, 11.383358086140052622000156781585004289033774706019),
|
||||
// Output from https://www.wolframalpha.com/input/?i=lambert_w0(1e6)
|
||||
tolerance); //
|
||||
@@ -609,36 +720,37 @@ BOOST_AUTO_TEST_CASE(test_range_of_double_values)
|
||||
// unknown location : fatal error : in "test_range_of_values": class boost::exception_detail::clone_impl<struct boost::exception_detail::error_info_injector<class std::domain_error> >: Error in function boost::math::lambert_w0<RealType>(<RealType>): Argument z = %1 too large.
|
||||
// I:\modular - boost\libs\math\test\test_lambert_w.cpp(456) : last checkpoint
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(1.7976931348623157e+308 / 2), // max_value/2 for IEEE 64-bit double.
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(1.7976931348623157e+308 / 2), // max_value/2 for IEEE 64-bit double.
|
||||
static_cast<double>(702.53487067487671916110655783739076368512998658347L),
|
||||
// N[productlog[0, 1.7976931348623157*10^308 /2],50] == 702.53487067487671916110655783739076368512998658347
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(1.7976931348623157e+308 /4), // near max_value/4 for IEEE 64-bit double.
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(1.7976931348623157e+308 /4), // near max_value/4 for IEEE 64-bit double.
|
||||
static_cast<double>(701.8427092142920014223182853764045476L),
|
||||
// N[productlog(0, 1.7976931348623157* 10^308 /4 ), 37] =701.8427092142920014223182853764045476
|
||||
// N[productlog(0, 0.25 * 1.7976931348623157*10^307), 37]
|
||||
tolerance);
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(4.4942328371557893e+307), // max_value/4 for IEEE 64-bit double.
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(4.4942328371557893e+307), // max_value/4 for IEEE 64-bit double.
|
||||
static_cast<double>(701.84270921429200143342782556643059L),
|
||||
// N[lambert_w[4.4942328371557893e+307], 35] == 701.8427092142920014334278255664305887
|
||||
// as a double == 701.83341468208209
|
||||
// Lambert computed 702.02379914670587
|
||||
// Lambert computed 702.02379914670587
|
||||
0.000003); // OK Much less precise at the max edge???
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0((std::numeric_limits<double>::max)()), // max_value for IEEE 64-bit double.
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0((std::numeric_limits<double>::max)()), // max_value for IEEE 64-bit double.
|
||||
static_cast<double>(703.2270331047701868711791887193075930),
|
||||
// N[productlog(0, 1.7976931348623157* 10^308), 37] = 703.2270331047701868711791887193075930
|
||||
// 703.22700325995515 lambert W
|
||||
// 703.22703310477016 Wolfram
|
||||
tolerance * 2e8); // OK but much less accurate near max.
|
||||
|
||||
// This test value is one epsilon close to the singularity at -exp(1) * x
|
||||
// Compare precisions very close to the singularity.
|
||||
// This test value is one epsilon close to the singularity at -exp(-1) * x
|
||||
// (below which the result has a non-zero imaginary part).
|
||||
RealType test_value = -exp_minus_one<RealType>();
|
||||
test_value += (std::numeric_limits<RealType>::epsilon() * 1);
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(test_value),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(test_value),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999996349975895),
|
||||
tolerance * 1000000000);
|
||||
// -0.99999996788201051
|
||||
@@ -646,30 +758,64 @@ BOOST_AUTO_TEST_CASE(test_range_of_double_values)
|
||||
// Would not expect to get a result closer than sqrt(epsilon)?
|
||||
} // if (std::numeric_limits<RealType>::is_specialized)
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36)),
|
||||
// Can only compare float_next for specific type T = double.
|
||||
// Comparison with Wolfram N[productlog(0,-0.36787944117144228 ), 17]
|
||||
// Note big loss of precision and big tolerance needed to pass.
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check float_next(-exp(-1) )
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(double, -0.36787944117144228)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999998496215738),
|
||||
1e8 * tolerance); // diff 6.03558e-09 v 2.2204460492503131e-16
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check float_next(float_next(-exp(-1) ))
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(double, -0.36787944117144222)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999997649828679),
|
||||
2e7 * tolerance);// diff 2.30785e-09 v 2.2204460492503131e-16
|
||||
|
||||
// Compare with previous PB/FK computations at double precision.
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check float_next(-exp(-1) )
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36787944117144228)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999997892657588),
|
||||
tolerance); // diff 6.03558e-09 v 2.2204460492503131e-16
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check float_next(float_next(-exp(-1) ))
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36787944117144222)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999997419043196),
|
||||
tolerance);// diff 2.30785e-09 v 2.2204460492503131e-16
|
||||
|
||||
// Comparison with Wolfram N[productlog(0,-0.36787944117144228 ), 17]
|
||||
// Using conversion from double to higher precision cpp_bin_float_quad
|
||||
using boost::multiprecision::cpp_bin_float_quad;
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check float_next(-exp(-1) )
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(cpp_bin_float_quad, -0.36787944117144228)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999998496215738),
|
||||
tolerance); // OK
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION( // Check float_next(float_next(-exp(-1) ))
|
||||
lambert_w0(BOOST_MATH_TEST_VALUE(cpp_bin_float_quad, -0.36787944117144222)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.99999997649828679),
|
||||
tolerance);// OK
|
||||
|
||||
// z increasingly close to singularity.
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.36)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.8060843159708177782855213616209920019974599683466713016),
|
||||
2 * tolerance); // -0.806084335
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.365)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.365)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.8798200914159538111724840007674053239388642469453350954),
|
||||
5 * tolerance); // Note 5 * tolerance
|
||||
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.3678)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.3678)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.9793607149578284774761844434886481686055949229547379368),
|
||||
15 * tolerance); // Note 15 * tolerance when this close to singularity.
|
||||
|
||||
|
||||
|
||||
// Just using series approximation (Fukushima switch at -0.35, but JM at 0.01 of singularity < -0.3679).
|
||||
// N[productlog(-0.351), 50] = -0.72398644140937651483634596143951001600417138085814
|
||||
// N[productlog(-0.351), 55] = -0.7239864414093765148363459614395100160041713808581379727
|
||||
BOOST_CHECK_CLOSE_FRACTION(jm_lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.351)),
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_w0(BOOST_MATH_TEST_VALUE(RealType, -0.351)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -0.72398644140937651483634596143951001600417138085814),
|
||||
10 * tolerance); // Note was 2 * tolerance
|
||||
// fails for JM version.
|
||||
|
||||
|
||||
// Not using near_singularity series approximation.
|
||||
// Check value just not using near_singularity series approximation (and using rational polynomial instead).
|
||||
BOOST_CHECK_CLOSE_FRACTION(lambert_wm1(BOOST_MATH_TEST_VALUE(RealType, -0.3)),
|
||||
BOOST_MATH_TEST_VALUE(RealType, -1.7813370234216276119741702815127452608215583564545),
|
||||
// Output from https://www.wolframalpha.com/input/
|
||||
|
||||
Reference in New Issue
Block a user